TDD对于小型项目来说是否过度设计?

44

我最近一直在阅读关于TDD等方面的文章,但我还不完全看好它。我制作了许多小型爱好项目(只有我一个人),我担心尝试使用TDD是否过度kill掉这些项目。虽然我曾经看到过像三名开发人员一样进行TDD的小型开源项目。(虽然我也看到了一些单人项目也使用TDD)

那么,TDD总是值得做的吗?在什么阈值下才有意义呢?


3
测试、测试驱动开发和单元测试是三个不同的概念。有些应用程序对单元测试毫无益处。并不存在“一刀切”的解决方案、设计或者实践。 - Egor Pavlikhin
很疯狂,大多数人都在缩写TDD,但是在原始帖子中从未将其扩展为“测试驱动开发”(Test-driven development)。 - zanlok
TDD 不仅仅是测试/质量保证,它还可以改进架构(更松散耦合的模块)和可维护性(如果想知道模块做什么以及如何使用它,请阅读模块的单元测试)。 - k3b
17个回答

47

小项目往往会在你意识不到的情况下成长为大项目,然后你会希望从TDD开始:)


36

在小型项目中,TDD表现出色。在小项目中遵循TDD通常更容易,并且这是练习并掌握遵循TDD所需的纪律的好时机。

根据我的经验,在一些阈值上,较大的项目往往放弃了TDD。(我并不认为这是一件好事)。

我认为,大型项目之所以放弃TDD,有以下几个原因:

  • 开发人员缺乏经验-无论是总体还是在TDD方面
  • 时间限制-较大的项目本质上更加复杂
    • 增加的复杂性会导致截止日期超过期限,单元测试往往会被放弃
    • 这可能会受到一个经验不足的团队的影响

4
我有一个朋友曾试图在一家相当大的公司引入TDD,虽然他们认识到了它的好处,但仍坚持使用广泛采用的代码和修复模型^^。 - helpermethod
12
另一个导致被遗弃的原因是:没有花足够的时间重构测试代码本身。测试代码很容易变得混乱不堪!如果你不关注这个方面,那么对基础结构的更改可能会产生重大的级联影响。无论如何,加油吧! - roufamatic
1
@roufamatic:完全正确。就像代码随着时间的推移会逐渐腐烂一样,测试也会如此,并且编写可维护的单元测试需要实践(通常从不正确的方式开始,通过吃亏来学习)。除此之外,我见过一些人犹豫是否重构测试,好像测试是神圣不可侵犯的一样。 - Mathias
2
+1:时间限制 == 管理层拒绝接受变革。太多时候,是管理层坚持要求人们停止测试,直接开始编写代码。 - S.Lott
@routamatic——TDD代码膨胀是一个很大的问题。问题是:如何防止它?有一个答案几乎没有人知道,因为他们从未被教过:契约式设计!为什么?因为你想要做的大部分“测试”实际上都是关于Hoare逻辑的前置条件和后置条件(以及检查条件、循环不变量和类不变量)。当测试断言在正确的位置得到适当应用时,它可以消除TDD代码膨胀。拥有一个知道如何在编译时剥离DbC断言的编译器对于使这项工作起作用至关重要。欢迎来到Eiffel和EiffelStudio。 - Liberty Lover

23

根据我的个人经验,我可以说:

  1. 每当我开始一个个人小爱好项目时,我都发誓要使用TDD进行开发。
  2. 但每一次我都没有这样做。
  3. 每一次我都后悔了。

13年过去了,这种情况仍然存在吗? - Vinn

17

所有事情都有一个收益成本曲线。

尽管忽略了许多经常争议的TDD优点,但如果您的实现将经常更改,以至于拥有自动化测试套件的好处超过了初始开发可能涉及的任何额外成本,那么使用TDD是值得的。


1
实现总是在变化,代码是一个活的东西,特别是在大型项目中...而且你永远不知道在引入即使是一个小改变时是否破坏了某些东西,如果没有单元测试。 - BlueLettuce16

11

我总是觉得像这样的问题很有趣。那另一种选择是什么呢?编写只编译而不运行以验证其正确性的代码吗?你会等到部署到生产环境才发现你的类根本无法工作吗?

如果我们从来没有一种叫做TDD的实践,或者在JUnit于1997年被发明之前,就没有代码测试了吗?当然还是有的。那么为什么现在有了测试框架帮助你进行测试后,它变得如此重要呢?

即使是在时间紧迫的小项目中,也不想等到生产环境才发现是否可行。写测试。

对于任何“小”的项目来说都不是必要的,但我定义的“小”是指少于一个类的项目。


3
我认为有两种选择可以使这个问题变得合理(而不是滑稽):(1)手动测试,和(2)在事后编写自动化测试,而不是之前。 - Kaleb Pederson
2
说实话,我认为TDD并不比(1)或(2)更费力 - 这就是为什么有点幽默。 - duffymo
2
+1:TDD与什么相比?“手动”测试?这是否意味着由希望能够通过外部接口运用所有类接口的人员完成的不完整测试。基于实现代码的事后测试?我认为这些都不是可行的替代方案。仅仅因为我参与过尝试这样做的项目(已经有30年了),并不意味着它们是可行的替代方案。 - S.Lott

7

过度吗?一点也不。除了主要的好处——编写可靠的代码,因为你考虑到了它可能出错的方式,采用测试驱动开发还能让你更加纪律严明,潜在地提高生产力。可以参考《程序员修炼之道》等任何一本务实的程序员书籍获取技巧和灵感。


6

我建议你在一个小项目中使用TDD,以便了解其工作原理。即使你发现它不适合你,这也是一个很好的学习经验。


6

我听到过我们当地敏捷小组的一位成员说,她认为在项目的最初阶段中并不需要使用TDD。那个时候你只是在草草画图,还不确定事物的形状。但是一旦你有了一些关于接口长什么样子的想法,就可以开始使用测试来帮助定义它们。

TDD和文档一样是提高代码清晰度的工具。这对其他人需要与你的代码一起工作的情况至关重要,但许多人发现当他们回顾自己的代码时,它也非常有用。你曾经有过一个业余项目,在离开一段时间后重新开始,发现一些奇怪的代码,然后想问:“我为什么写了那个?”


4

我和其他人在编写超过几行代码的任何项目时都使用TDD。

一旦你被测试的热情所感染,就很难不在任何项目中使用TDD。个人经验是,由于TDD的使用,我的代码质量提高了好几倍。


TDD让我变得懒散了。编写测试很简单。一旦写好,编写用于通过测试的代码通常更容易理解,因为这个过程是在写测试时完成的。 - S.Lott
1
TDD让我的代码变得更好了。首先我编写一个能够正常工作的解决方案,然后我可以引入修改和改进(如设计模式),而不必担心破坏原有功能。 - BlueLettuce16

3

我相信对于大多数项目来说,这是值得的。测试驱动开发(TDD)及其相关的 回归测试 不仅可以在编写组件时确定其是否正常工作,而且还可以在引入更改和重构时进行测试。只要你的测试足够完整,就可以覆盖不常见/不可能出现的边缘情况,并生成/维护更可靠的代码。

在项目生命周期中向前推进,连续的测试周期将节省您手动重复测试的时间,并消除了重复测试时出现错误或不完整的明显机会。


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