新手TDD推荐使用的工具

8

我对TDD世界非常陌生,有几个关于TDD的问题。

  1. 在TDD中必须先进行测试吗?我听说TDD不是关于测试而是关于设计。我认为先进行测试是好的,但我想知道如果我们采用最后才测试的方法是否仍然算是TDD?

  2. 我们应该优先选择BDD还是TDD?我过去习惯先列出任务的规范,然后尝试根据规范编写测试用例。这种方法错了吗?你们是更喜欢使用BDD还是TDD进行开发?

  3. 模拟?我的团队中有些人说他们正在实践TDD。但是他们从来不遵循测试优先的方法,也不会模拟数据。在TDD中是否需要模拟数据?

  4. “使用Mock库”与“手动创建具有模拟数据的Mock类”。您更喜欢使用Mock库还是创建带有一些模拟数据的Mock类?

  5. 有关TDD或BDD的任何推荐书籍吗?我读过肯特·贝克(Kent Beck)经典的《测试驱动开发——示例》。我发现这本书发行时TDD处于早期阶段,因此书中的某些内容有点过时。


实际上,我认为TDD对代码库有一些非常负面的影响(糟糕的设计,过程式代码,没有封装,生产代码中充斥着测试代码,到处都是接口,很难重构生产代码,因为所有东西都与许多测试紧密耦合等)。从这个链接中可以看到一些有趣的事情。https://dev59.com/U3VD5IYBdhLWcg3wHn2d - Mark
+1 对于深思熟虑的问题。 - pierrotlefou
@Mark:这是你的真实经历吗?就我个人而言,TDD 对我来说是一个重要的领悟时刻,并通过迫使我清晰地思考每个类应该做什么 - 以及不应该做什么,帮助我更好地理解封装。关于“到处都是接口”,我可以通过模拟看到,但相反,TDD 也推动你去实现一些有效的东西,而不是进入架构宇航员模式。嗯...希望我听起来不像 TDD 狂热者 :) - Mathias
@马克,又来了。话虽如此,我最初尝试单元测试的结果并不令人满意。我编写了许多脆弱的单元测试,这些测试会创建自己的维护问题。编写良好、可维护的单元测试需要付出努力和实践,就像编写常规代码一样。 - Mathias
7个回答

3

1). 我在TDD中必须先测试吗?我听说TDD不是关于测试,而是关于设计。我同意先做测试很好,但我想知道如果我们采用最后测试的方法,它是否仍然是TDD?

是的! 严格来说,TDD是测试驱动开发。因此,开发是由测试驱动的。所以您首先进行测试,然后开发程序以通过所有测试。

2). 我们应该优先使用BDD还是TDD?我过去习惯先列出我的任务规格,然后尝试根据我的规格编写测试用例。这是否是错误的方法?你们更喜欢使用BDD还是TDD进行开发?

我认为你应该平衡它们。首先使用其他技术提供整体设计,尽可能做好风险管理以找到你应该花费在设计上的适当时间(查找关于 "RUP essential" 的论文,它提供了一个很好的平衡敏捷和非敏捷的想法)。确定最关键的部分,然后创建测试并开发以通过测试。

3).Mocking?我的团队中有些人 声称他们正在实践TDD。但是他们从不遵循测试优先的方法。 他们从不模拟数据。我们在TDD中必须模拟数据吗?

测试优先和模拟不是同一回事。模拟使代码更易于测试,同时在其他部分不存在时也可以进行测试(这个代码依赖的部分不存在)。因此,如果没有这样的依赖关系(如果!!),则可以不模拟它们。(阅读关于与遗留代码有效地工作的Seam点的更多详细信息)。

4). “使用Mock库”与“手动创建具有模拟数据的Mock类”。您更喜欢使用Mock库还是手动创建Mock类?

我认为这就像使用别人的库或创建自己的库一样。完全取决于情况和许多因素。例如,如果您的项目很大并且可以找到适当的Mock库,则使用它。

5). 有没有推荐的TDD或BDD书籍?我读过肯特·贝克(Kent Beck)经典的《测试驱动开发:通过示例证明》。我发现这本书是在TDD的早期阶段出版的,所以其中一些内容已经过时了。

这里有TDD书籍清单

希望这可以帮助。


2
  1. 是的,这与设计有关,但这种设计方法确实涉及先编写测试。人们对此规则的遵循程度不同,但我认识的大多数TDD实践者倾向于认为遵循规则更好。
  2. BDD被描述为正确执行的TDD。两者之间的区别很小。本质上,BDD只是更明确地将测试作为规范的一部分。
  3. 关于mock的用处存在很大争议。我个人更喜欢测试接口,并避免在mock中设置期望值。尽管如此,出于各种原因,隔离测试仍然是一个好主意,其中最重要的是测试速度。没有比重构一段代码更烦人的事情了,而这段代码仍然完全符合以前的接口,有一个完全工作的结果,但是所有测试都失败了,因为mock的期望值不再满足。不良的mock使用导致测试实现细节而不是确保执行的工作正确。
  4. 见#3。我更喜欢只使用一个没有期望值的存根或者使用集成测试。
  5. 《Test-Driven Development: A Practical Guide》by Dave Astels。强烈推荐。

1
我必须在TDD中进行测试吗?
是的,实际上TDD就是这样的:
vagueness -> bullet points -> tests -> code

如果您正在使用其他过程,使用一些工具和技术可能是有意义的,但它实际上不是TDD。无论价值多少。

模拟?

有4个或多或少可行的替代方案,不同的大师会提倡不同的方法。

  1. 零模拟:模拟每个依赖项,使得每个单元(例如Java类)都被有效地隔离测试。

  2. 线性模拟:仅模拟循环依赖项,以便有一个线性的测试顺序,每个单元只与已测试的依赖项一起测试。

  3. 速度模拟:仅模拟缓慢、异步或其他有问题的接口。

  4. 零模拟:只是测试东西,如果出现问题,请使用调试器解决问题。

如果您不喜欢您的模拟工具,请避免使用#1,如果您不喜欢您的调试器,请避免使用#4。


1

0
我在TDD中一定要先测试吗?
是的,TDD必须是先测试。先编写测试可以让您以行为为基础思考要编写的函数,而不是根据实现方式进行思考,重点放在调用函数和验证结果上。 这将导致可测试的代码;否则,您可能会陷入死胡同。 首先编写测试还可以更容易地避免忘记或忽略测试。
此外,编写并失败的测试可以测试测试。在编码后编写的测试可能永远不会失败。
我们是否应该优先使用BDD而不是TDD?
有些人认为BDD是正确实施TDD的方法,因为其侧重点是在规范上。
在TDD中我们必须模拟数据吗? 我的团队中有些人说他们正在练习TDD。但他们从未遵循过测试优先的方法。
您不必使用模拟对象。它们只是一种工具,有时可能很方便。
使用Mock库与手动创建带数据的模拟类相比较。
我从未感到需要使用模拟对象生成器。
有没有推荐的TDD或BDD书籍?
《测试驱动开发:实战与模式解析》是一个非常好的教程,介绍了许多模式。另一本很棒的书,更像是一本参考书,是xUnit patterns

0
  1. 是的,先进行测试是TDD的主要思想。
  2. 如果你两者都没有经验,我建议从TDD开始入门(个人观点)。
  3. 在进行TDD时,并不一定非得使用mock。但是,如果你的应用程序中有依赖于其他类的类(这几乎是必然的),你会遇到mocking。顺便说一下,mocking并不是模拟数据,而是模拟正在被测试的类与其协作者之间的交互,即其依赖的另一个或多个类。
  4. 手动mocking是理解mocking的好方法,但如果你不想花费大量时间编写虚假实现,使用mocking/隔离框架更加可取。
  5. 在我看来,Beck的书是不朽的经典,是入门的好起点。如果你使用.NET,我刚刚读过的《单元测试的艺术》详细介绍了单元测试的良好技术和实践。

谢谢。我有单元测试的经验,甚至几年前为QA团队开发了一个带有一些自定义功能的单元测试框架。但是,确实没有在真实项目中尝试过TDD。当我开始编写代码之前编写单元测试时,我并不太适应。当我尝试BDD时,它似乎更符合我的需求。它更易读,知道要测试什么(规范),以及何时结束(规范)。我对TDD和BDD都没有深入研究,但我可能在TDD方面错过了一些东西。你们真的更喜欢TDD吗?难道你们不觉得编写比规范文档中更多的单元测试有点奇怪吗? - Mark
这可能取决于您团队中的流程和您编写的代码类型。通常我没有太多的规格说明可以开始编写测试,所以先编写测试并不是一个问题,它有助于明确规格说明,并找出问题。我发现在设计系统时先编写测试非常有用,因为它强制您“可视化”将要创建的内容,并考虑如何使用它,就好像它已经完成了一样。它有助于专注于您的目标。 - Mathias

0

1
关于BDD呢?市场上有没有BDD的书籍? - Mark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接