如果TDD与设计有关,为什么需要它?[关闭]


10

TDD专家越来越多地告诉我们TDD与测试无关,而与设计有关。因此,我知道有些开发人员在没有TDD的情况下创建了非常出色的设计。他们应该练习TDD吗?


14
如果没有它,他们做得很好,那么他们就不需要它。并非每种“最佳实践”都适合所有人。
Rook

Answers:


18

TDD不仅可以帮助我达到最佳的最终设计,还可以帮助我减少尝试次数。

在决定我认为最好的设计之前,我曾经遇到过两到三个刺。现在,花了相同的时间编写测试并将我的注意力集中在正确的设计上。而且,作为奖励,它给了我一套可重复的测试。赢得!

就是说,不可避免地会有一些人,而TDD对此却一无所获。只要他们在最后仍具有自动化的可重复测试,就可以了。


4
尝试更少,真的吗?
SiberianGuy

3
对真的。TDD迫使我根据调用代码及其功能来考虑类,因为您首先要编写希望编写的代码以消耗该类。当我写一个“盲”类时,我倾向于把重点放在它比调用类期望的功能更多上,这几乎总是一个错误。
pdr

4
瞧,又是那个词forced。我不知道为什么人们在有关TDD的讨论中不经常被“强迫”一词的频率打扰。不必强迫别人正确地设计东西。他们应该学习如何正确设计事物,然后继续这样做而不会被迫参与其中,尤其是当这种强迫行为非常耗时时。
宫坂丽

3
@Rei:人们不会经常被打扰,因为他们知道对方确实是“推”或“指导”或...的意思,这是当您谈论测试驱动开发时的启示...也许是“驱动”的。是的,有些人可能会发现他们自然地以这种方式思考,没有被驱使,我在帖子中说过。但是您仍然必须测试您的软件,因此您的状况不会更好。
pdr

3
当有人说“强制模块化设计”时,他们确实是被迫的。用TDD进行非组合设计非常困难(如果不是不可能的话),这是一件好事。问题不在于强制性的最终结果。这是需要花力,死记硬背的努力。适当的设计是一种可教导学习的技能,应该花时间在学习上。另外,为TDD编写的测试看起来与为捕获错误而编写的测试不太相似。如果他们这样做,那是不对的
宫坂丽

12

这个特定的 TDD专家真正想说的不是TDD是一个设计过程(尽管不幸的是,许多人以这种方式对其进行了解释)。此处的信息是,如果正确执行,则使用TDD之类的流程会改善整体设计。

基本概念是一个比TDD古老得多的概念。设计可测试性。如果您严格遵守SOLID原则,尤其是“ 单一职责原则”,您将发现代码非常易于测试。另一方面,如果您的设计趋于太草率,则可能会发现编写单元测试以迫使您更频繁地执行此操作的过程,以避免(a)弄清楚需要做什么的挫败感。被测试,并且(b)花更多的时间来建立依赖关系,而不是编写实际的测试。

你不必遵循TDD得到这样的好处,但它确实有助于编写测试初期 -你实现一个下课后最好很快,如果不是之前或期间。如果等待时间太长,则冒着作者所说的“肮脏混合”测试的风险,该测试没有太大价值,因为它们易碎,在无害重构中容易破裂-更不用说扩大规模重新设计了极其困难的过程。

如果您不编写测试,就不会知道您是否真的在设计可测试性,而仅覆盖15%代码的偶然性“功能测试”就不算在内。

当然,您无需编写任何测试就可以创建好的设计-但是您确定它们是很棒的设计吗?您怎么知道,如果测试没有明确指定您的名字?测试发现了很多问题,尽管质量检查流程可能会发现明显的错误,但它们不会发现不良的设计决策。


1
好的设计的重点不仅仅是测试。但是是的,TDD是发现有缺陷的设计的好工具。
deadalnix

4

努力学习TDD的人给出了一个简单的答案:您不需要它,但是,它给您带来的主要好处是,很简单,就是信心:对您的应用程序有效的信心。对用例得到满足的信心。确信您对“ Foobar”模块的逻辑是正确的。当首席执行官想要添加他所读过的一些新的疯狂功能时,您有信心在六个月内将您的代码正确地构造为可维护和可扩展。有信心,当您的应用程序增长时,该架构已奠定基础,使其不会崩溃或需要杂乱无章的黑客来评审新功能。

我意识到以上内容听起来有些福音,但这就是我看到TDD好处的方式。即使您可以使用TDD创建好的,坚实的,结构合理的设计,也可以使您的手正确地做事,然后证明事情做对了,更重要的是提供了使事情做对的基线。从我涉足TDD的很小一部分开始,使用它就迫使我使代码变得干净并遵循正确的软件工程概念,否则我将做“最快速的事情”,这常常导致混乱的“ hack”代码。


+1 TDD是反馈。随着大多数反馈措施的采用,它是相当客观且完全自动化的,因此可以由所有技能水平的团队成员共享。在TDD之前,好的代码是您“感觉到”的东西,或者在用户获得软件后的某个时间被确认。循环越短,您就越有信心。不幸的是,TDD容易过份自信,因为它“感觉”到一个好的设计,但是它更容易自我修正。
史蒂夫·杰克逊

2

我只能从我的经验谈起。对我来说,TDD在我的开发风格习惯工具箱中带来了一些以前没有的东西。虽然,值得一提的是TDD并不能解决所有问题。我总是尝试将勘探和生产准备实施分开。绝对不需要勘探阶段的TDD,甚至正在放缓。另一方面,针对生产就绪型代码,它带来了一些好处,无论从长期还是长期来看,这对于开发人员的心理健康和项目业力都非常有价值。

  • TDD使我在实施之前进行思考,这通常是很好的做法,可以避免很多麻烦而忘记解决方案
  • 它使我只想一小部分问题,迫使我将解决方案分解为适合在一起的小部分。
  • 它使我编写了非常分离的代码,因为每当我不得不对不适合该问题的东西进行存根/模拟/伪造时,我自然会抛出一个“ WTF,如果我不必将其与之耦合,那我为什么要这样做” 。它使我更好地了解事物之间的联系。
  • 它为我的代码提供了一组易于执行的检查,因此我不必经历痛苦的​​“ var_dump”,“ p”,“ pp”,“ echo”样式的代码调试。它只是报告什么地方有问题,什么时候有问题。而且,如果我还没有检查的地方,那就只是添加简单的测试来一遍又一遍地检查它。
  • 这使我确信,如果在部署之前所有测试都通过了,我的代码就可以工作。然后,我不吃指甲而是去吃蛋糕,喝咖啡和享受下午的时光。
  • 在必须重构某些情况下,高级测试非常好。如果我的模块必须向外界提供某些功能,并且我已经开发了功能/集成/黄瓜测试以证明其工作正常,那么我将非常勇敢地从代码中重构出地狱。有几次我遇到了没有测试并且需要重构的代码。在这种情况下,有两种方法可以实践。1)删除代码2)跳过更改并保持原样。

TDD无法解决的一件事。如果您不知道如何构建要构建的东西,那么TDD将不会为您提供解决方案。您需要对问题和解决方案进行粗略的“设计”或概述。TDD将使您以更高质量的代码以更加优雅和可维护的方式实现它。

最后,我更喜欢以BDD术语为基础进行思考,该术语依赖于TDD的实践。BDD使我能够使用领域的词汇来实现解决方案,并使软件更好地解决问题。


1

可能有很多方法可以实现出色的设计,而且毫无疑问,对“伟大”甚至“好”的构成有许多不同的解释。我怀疑大多数TDD人士都不会同意您的定义-如果我们看一下您认为很棒的代码,就会认为它不尽人意。TDD将我们带入某些非常特殊的品质,而在非TDD代码中很少发现这些品质。

可测试性显然是这些特质之一,也是最重要的特质之一。极小的方法和类可能是子特性,这导致了出色的命名。也许您知道不执行TDD就能达到这些素质的程序员,但是我不知道。


1
您几乎肯定会在瀑布过程产生的代码中找到这些相同的品质,例如用于军事,太空等。我想这确实是在半熟练的敏捷和/或瀑布实践中不常见的版本。大多数组织用于日常项目。
亚伦诺特,2011年

@Aaronaught告诉火星气候轨道器团队。:-)
埃里克·金

我对90年代非武器军事项目的瀑布处理过程有一些经验,并且还与其他军事用途的退伍军人进行了很多讨论。普遍的共识是瀑布方法和成本加计价产生了难以维护的越野车系统。
凯文·克莱恩
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.