TDD:在第一次单元测试之前会发生什么?


17

我最了解TDD的理论,但我不知道如何开始。我坐下来为个人项目编写单元测试并意识到这一点。。。我不知道我要测试什么。什么对象,什么功能等

例如,假设我想编写一个应用程序来帮助我们的家人管理杂务。我想到了一些问题:如何从这个想法开始进行第一次测试?开始之前应该确定多少?开始编写测试后应该确定多少?什么时候做出诸如将数据存储在文本文件还是数据库中的决定?开始之前是否应该进行用户接受度测试?我应该设计UI吗?我应该有规格吗?(我确实意识到这些示例问题中至少有一些可能在“灰色区域”中)。

除了有关进行第一个单元测试的标题问题之外,您还可以举一个例子说明一个示例项目的项目的第一个单元测试是什么样的吗?


5
我完全推荐阅读Nat Pryce和Steve Freeman所著的GOOS书籍……关于通过“薄层”功能进行端到端测试的一些很好的信息。
空白:

Answers:


6

我想从功能列表开始,为每个功能写用户故事,然后为每个故事写测试描述。

仔细考虑一下设计,然后选择一个测试描述并开始编码:red-green-refactor。

重复直到所有测试通过。

是的,应将接受测试视为其中的一部分,并附在适当的故事中。


我喜欢这个。我可以遵循一个非常清晰的过程:列出功能,为每个功能创建一个用户故事的子列表,为每个用户故事创建一个测试的子列表。我将尝试该过程。
Ethel Evans

我接受这一点是因为它满足了我个人想知道的内容,但是建议人们也阅读卡尔的(更多支持)回复。
Ethel Evans

18

您从一开始就发现TDD与设计有关。在编写第一个测试之前,您必须考虑一下您的第一个功能是什么,以及如果该功能正常工作,程序将是什么样。

不使用TDD的开发人员也必须考虑这一点-但他们可以“深入研究”并开始编写任何东西。但是“东西”并不总是在交付您认为打算编写的程序的道路上。什么是?好吧,如果程序正常运行,它将是什么样?它会通过什么测试?

我想编写一个应用程序来帮助我们的家人管理杂务。

凉。如果该应用程序正常运行,它将怎么办?好吧,杂务可能会分配给一个人,对吧?

Person fred = new Person("fred")
Chore mow = new Chore("mow the lawn");
mow.assignTo(fred);
assertEquals(fred, mow.whoIsAssigned());

有一个开始。不是您必须开始的地方,不一定是最佳开始的地方-但这是一个地方。您希望代码支持该功能(尽管我敢肯定您可以提供更好的名称)。从那里开始,观看失败。让它通过。清理。泡沫,冲洗,重复。


我不喜欢这个例子,但是我同意这个前提。仅当您能够并且愿意至少进行一些前期设计时,测试优先方法才有意义。实际上,您实际上确实需要一个骨架域模型,或者至少需要一个相当大的块。
亚罗诺(Aaronaught)2011年

5
这里没有前期设计。测试中的任何类都不需要存在。设计在测试中进行,然后创建它们以通过测试。
–Torbjørn

您能否详细说明“编写第一个测试之前,您必须考虑一下您的第一个功能是什么,以及如果该功能正常工作,程序将是什么样子。”?开始之前我应该​​解决多少?在什么时候我过度设计而失去了让单元测试驱动设计的好处?我假设我不想要类图,它应该由重构来驱动,对吗?但是这个例子听起来像是“有个主意,花15秒钟思考,然后编写测试”。那真的就是我想要做的吗?
Ethel Evans

2
@Ethel是的,这与我建议放入其中的想法差不多(在此示例中以及一般而言)。找出可测试的东西,将您引向所需的产品,然后为它编写测试。
Carl Manaster 2011年

1
如何在团队中工作是一个更大且不同的问题。TDD本身在协调团队合作方面没有太多发言权。结对编程和规划游戏可以为您提供帮助;在您计划的范围内,TDD仍然适用。jamesshore.com/Agile-Book/the_planning_game.html Scrum对于如何计划团队的工作也有话要说。
卡尔·曼纳斯特

5

是的,TDD存在此问题。这就是为什么我现在推荐行为驱动开发。

手动启动。写下类似于用户故事的内容:

  • 作为用户
  • 当我选择添加到购物车时,我希望该产品在后台透明添加
  • 这样我就可以不间断地继续购物

现在,支持该目标的功能是什么(“那个”部分)?

  • 将商品添加到购物车时
    • 用户的购物车将包含新商品
    • 购物车中的总物品数将增加一
    • 不应重定向用户
    • 立即签出选项将可用
  • 当购物车中有两个项目并且用户选择结帐时
    • 用户将被重定向到检出页面
    • 两项均可见

这些都是您可以做的,应该手动检查。

做一会儿。然后,像一个优秀的开发人员一样,开始寻找使冗余零件自动化的方法。具体取决于您的平台是什么,但是大多数平台都有不错的框架。

.Net具有用于自动化网页的WatiN,或者,如果您要测试API,我建议向xUnit或MSpec中添加Subspec(您也可以在任何测试框架中进行此操作,只是通过这些方法可以更轻松地命名测试名称支持这种思维方式)。

Ruby具有用于自动化测试的黄瓜和用于较低级别API测试的rspec

Javascript具有茉莉花和qUnit。

点点


有黄瓜克隆/对.NET的替代品也:看到这个StackOverflow的问题
Carson63000

@ Carson63000是的,但是我个人没有多大意义。Ruby是IronRuby中的.Net语言。只需创建一个IronRuby项目并使用实际的黄瓜即可。
乔治·莫尔

我喜欢BDD,并使用StoryQ。别忘了提到,可以使用Given / When / Then将故事扩展到各种故事。鉴于发生了一些事情,当我执行此操作和此操作时,然后我希望进行此操作。在TechEd channel9.msdn.com/Events/TechEd/NorthAmerica/2010/DPR302上查看David Starr的演讲,如果您使用的是.net storyq.codeplex.com
访问

3

我如何从这个想法进入我的第一个测试?开始之前应该确定多少?开始编写测试后应该确定多少?

将您的应用程序分解成小故事。(“作为用户,我想双击一个图标并启动程序。”或“作为用户,我想打开浏览器并转到该程序。”无论如何。)

然后将故事分解为一些任务。(例如,在Eclipse中创建一个项目,建立一个代码存储库)当您完成编码任务时,编写您的第一个测试。

什么时候做出诸如将数据存储在文本文件还是数据库中的决定?

如果不确定,请选择哪一个似乎更简单,然后执行此操作。(可能是文本文件)如果您发现自己犯了一个错误,请重构。如果您的测试结构合理,则应该能够进行后端更改并捕获意外的副作用。


3

我很惊讶,没有一个答案包含的实际一提的事,你正确的写你的第一次测试,这是之前创建一个测试清单。测试列表由其他答案中提到的故事编写和设计阶段提供,并且是编写您似乎正在寻找的测试的直接先驱。

有关TDD的更多信息,我建议使用Kent Beck的“ 示例测试驱动开发”。他还做了一个TDD截屏视频,该视频以纯TDD风格开发了一个非平凡的库,并在此过程的每个步骤中都有Kent的解释。我认为这是TDD在实践中的一个很好的例子,即使它(在必要的情况下)在人为的环境中完成也是如此。


0

在进行第一次单元测试之前,请先考虑要发生的事情,然后再考虑如何进行测试。然后编写该测试,查看它是否失败并实现一些代码以使其通过。

冲洗,重复等

对我来说,思考如何测试它很重要,这才是推动设计的要素。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.