TDD与单元测试的区别

120

我的公司在进行单元测试时比较新。我一直在阅读有关TDD和单元测试的文章,深信它们的价值。我尝试说服我们的团队,TDD值得学习和改变我们编程思维,但却很困难。这就带来了我的问题。

TDD社区中有许多人非常坚持先编写测试再编写代码(我也是),但对于一个正在努力理解TDD的团队来说,妥协还能带来额外的好处吗?

我可能可以让团队在编写代码后编写单元测试(作为检查代码的要求),我的假设是编写这些单元测试仍然具有价值。

如何最好地让团队接受TDD?如果失败,即使在代码编写后编写单元测试,是否仍然值得?

编辑

我从中得出的结论是,我们需要在编码过程中开始进行单元测试。对于那些理解这个概念的团队成员,应该开始更加倾向于TDD和先测试的编程方式。谢谢大家的建议。

后续

我们最近启动了一个新的小项目,团队的一小部分使用了TDD,其余的在编写代码后编写了单元测试。项目的编码部分结束后,那些在编写代码后编写单元测试的人惊讶地发现TDD编码者已经完成并且具有更加稳定的代码。这是赢得怀疑者的好方法。我们仍然有很多成长的痛苦,但意见之争似乎已经结束。感谢每个人提供的建议!


1
你可能会发现这个线程有帮助:https://dev59.com/nnNA5IYBdhLWcg3wjOlS - Randolpho
30
+1 表示后续跟进。那个故事很棒。 - Carl Manaster
17个回答

3

单元测试最有用的方面之一是确保已经工作的代码能够持续正确。当你可以任意重构代码,并让IDE提醒你编译时错误,然后点击一个按钮让你的测试发现任何潜在的运行时错误——有时会出现在以前微不足道的代码块中——我想你会发现你的团队开始欣赏TDD。因此,从测试现有代码开始肯定是有用的。

同时,坦率地说,通过尝试测试已经编写的代码来学习如何编写可测试代码,我比从TDD开始更加深入理解了这个过程。如果你试图考虑既能完成最终目标又允许测试的合同,它可能会太抽象了。但是当你看着代码并且可以说“这里的单例完全破坏了依赖注入,使得测试变得不可能”,你开始欣赏什么样的模式会让你的测试生活更加容易。


3
如果您在编写代码之前有设计会议或需要制作设计文档,则可以将单元测试作为会议的具体成果。这可以作为代码应该如何工作的规范。鼓励在设计会议上进行配对,让人们谈论某些东西应该如何工作以及在给定情况下应该做什么。哪些是边缘情况,为它们明确指定测试用例,以便每个人都知道如果例如给出空参数它将做什么。
另外 BDD 也可能会引起兴趣。

我之前不知道BDD,我需要多了解一下。 - Walter

3
你可以通过展示一两个例子来说明TDD能减少编写的代码量 - 因为你只编写必要的代码来使测试通过,所以更容易抵制过度设计或YAGNI。你不需要编写的代码也不需要维护、重构等,因此这是一个“真正的节省”,可以帮助推销TDD的概念。
如果你能清晰地展示在时间、成本、代码和缺陷方面的价值,你可能会发现它更容易被接受。

2
开始构建JUnit测试类是开始的方法,对于现有代码来说,这是唯一的开始方式。根据我的经验,为现有代码创建测试类非常有用。如果管理层认为这将花费太多时间,您可以提议仅在发现相应的类包含错误或需要清理时编写测试类。
对于维护过程,让团队接受这个方法的方式是,在修复错误之前编写JUnit测试以重现错误,即:
- 报告错误 - 如有必要,创建JUnit测试类 - 添加可重现错误的测试 - 修复代码 - 运行测试以显示当前代码不会重现错误
您可以解释说,通过这种方式“记录”错误将防止这些错误在以后再次出现。这是团队可以立即体验到的好处。

2
我在许多组织中都这样做过,我发现启动和遵循TDD的最佳方法是设置成对编程。如果您有其他人可以依靠,他们知道TDD,那么您两个可以分开并与其他开发人员配对,使用TDD进行一些成对编程。如果没有,我会在向团队介绍之前培训一些人来帮助您完成此操作。
单元测试,特别是TDD的一个主要障碍是开发人员不知道如何做,因此他们无法看到它值得他们投入时间。当您刚开始时,速度会慢得多,而且似乎没有提供任何好处。只有当您做得好时,它才真正为您提供好处。通过设置成对编程会话,您可以快速使开发人员能够快速学习它,并更快地掌握它。此外,当您一起工作时,他们将能够立即从中获得好处。
这种方法在过去多次为我奏效。

2

发现TDD的好处的一个强有力的方法是对某些现有功能进行重写,例如出于性能原因。通过创建一套测试用例,覆盖现有代码的所有功能,你可以充满信心地重构代码,而无需担心变更是否安全。

请注意,这里所说的是测试设计或合同 - 测试实现细节的单元测试在这里不适用。但是,根据定义,TDD无法测试实现,因为它们应该在实现之前编写。


1

TDD是开发人员可以使用的工具,以产生更好的代码。我认为编写可测试代码的练习与测试本身同样有价值。为了进行测试,隔离被测试的实现(Implementation Under Test)会导致您的代码解耦。

TDD并不适合所有人,也没有什么魔法可以让团队选择使用它。风险在于单元测试编写者不知道哪些值得测试,将编写大量低价值测试,这将成为您组织中TDD怀疑论者的炮灰。

我通常会使自动化验收测试成为不可协商的事项,但允许开发人员根据需要采用TDD。我让有经验的TDD者培训/指导其他人,并通过长达数月的示例“证明”其有用性。

这既是社会/文化变革,也是技术变革。


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