测试驱动开发(TDD)是否实际上使一个现实项目受益?


36

我对编码并不陌生。我已经(认真)编码了15年以上。我一直对我的代码进行一些测试。但是,在过去的几个月中,我一直在使用Ruby on Rails学习测试驱动的设计/开发(TDD)。到目前为止,我还没有看到好处。

我看到为某些事情编写测试有一些好处,但很少。尽管我喜欢首先编写测试的想法,但与调试实际代码相比,我发现我花费大量时间尝试调试我的测试,以使他们说出我的意思。这可能是因为测试代码通常比其测试的代码复杂得多。我希望这只是可用工具(在这种情况下为RSpec)的经验。

但是,我必须说,在这一点上,令人沮丧的程度加上令人失望的性能不足令人无法接受。到目前为止,我从TDD看到的唯一价值是不断增长的RSpec文件库,该库可用作其他项目/文件的模板。与实际的项目代码文件相比,这没有什么用处,也许没有用。

在阅读现有文献时,我注意到TDD似乎需要大量时间,但最终会获得回报。我只是想知道,有没有现实世界的例子?这种巨大的挫败感是否能在现实世界中得到回报?

我真的希望我不要在这里的其他地方错过这个问题。我进行了搜索,但是所有问题/答案都已经过了几年了。这是我难得的一次机会,当时我发现一个开发人员会对TDD不好说,这就是为什么我花了很多时间在此上的原因。但是,我注意到似乎没有人指出具体的实际示例。我确实读过一个答案,说在2011年调试代码的人会感谢您拥有完整的单元测试套件(我认为评论是在2008年提出的)。

所以,我只是想知道,在所有这些年之后,我们是否最终有任何例子表明收益是真实的?是否有人真的继承或返回了使用TDD设计/开发的代码,并具有完整的单元测试集,并且确实感到收获了?还是您发现您花了太多时间试图弄清楚测试正在测试什么(以及为什么它很重要),以至于您只是把整个混乱扔进了代码中?


1
它为我节省了更多时间:因为我们在同一项目上的人很多,因为gem更新可能会有一些未知的副作用,因为如果一切都是绿色的并且我有一个bug,我知道在哪里找不到它的根。
2012年


3
butunclebob.com/ArticleS.UncleBob.JustTenMinutesWithoutAtest这是鲍勃叔叔关于他所面临的现实世界的一个故事。
哈坎·德里亚

1
起初,我认为测试对于了解没有错误的地方将非常有用,但是正如@Hakan在Bob叔叔文章中指出的那样,我很快就学到了,通常是因为您错过了一个测试用例而出现的。这使得这些测试变得毫无用处。实际上,该文章指出了增量开发才是有效的。
詹姆斯

1
“与调试实际代码相比,与调试实际代码相比,我发现我花了更多的时间来调试我的测试,以使他们说出我的意思”:但这不就是好处吗?之后,您是否仍然发现您花费大量时间调试“实际代码”?TDD的支持者认为,花时间弄清楚使代码可测试的方法实际上是对代码有益的设计工作。
Andres F.

Answers:


26

本文表明,TDD增加了15-35%的开发时间,而在其他类似项目中,缺陷密度降低了40-90%。

文章指全文(PDF) - Nachiappan Nagappan,E.迈克尔马克西米,Thirumalesh铢,以及劳瑞·威廉姆斯。“通过测试驱动的开发实现质量改进:四个工业团队的成果和经验”。ESE 2008

抽象测试驱动开发(TDD)是一种已被零星使用的软件开发实践,通过这种实践,软件工程师在编写失败的单元测试和编写实现代码以通过这些测试之间逐分钟地进行循环。最近,测试驱动开发重新成为敏捷软件开发方法的关键支持实践。但是,很少有经验证据支持或驳斥这种做法在工业环境中的效用。案例研究由Microsoft的三个开发团队和IBM的一个采用TDD的开发团队进行。案例研究的结果表明,与未使用TDD做法的类似项目相比,四种产品的预发布缺陷密度降低了40%至90%。主观上

全文还简要总结了有关TDD及其高水平结果的相关经验研究(第3部分“ 相关著作”),包括George and Williams 2003,Müllerand Hagner(2002),Erdogmus等。(2005),Müller和Tichy(2001),Janzen和Seiedian(2006)。


2
通过对Meta.StackOverflow的讨论,您能否从本文中添加其他与问询者以及以后发现此问题的人相关的信息?
Thomas Owens

2
@ThomasOwens,我认为结论(“ TDD增加了15-35%的开发时间,以换取缺陷密度降低40-90%”)回答原始问题的其他信息<_ <

4
该帖子已被标记为没有包含足够的信息。我尚未阅读该论文,但看来人们希望在答案正文中添加更多信息。也许更多地讨论研究中使用的具体条件?
Thomas Owens

所有统计数据中有99%是虚构的。:P但实际上是关于上下文的。在什么样的团队上?一大批普通的Java开发人员?是的,我相信TDD将帮助他们提高生产力。但这并不意味着首先具有架构能力来设计和评估健壮的代码不会对他们有多大帮助,而IMO,测试优先的TDD可能很容易阻止他们学习如何正确地做到这一点。是的,我听说它对设计有帮助。从某种程度上讲,这可能是对的,但仍然没有得到承认,根本问题IMO并没有提供帮助。
Erik Reppen 2013年

如果从ACM数字图书馆中列出了更多论文,或者添加了用于搜索引擎的关键字,那就太好了。在谈论敏捷和TDD时,我们需要更加严格的答案
Rudolf Olah 2013年

16

我看到为某些事情编写测试有一些好处,但很少。尽管我喜欢首先编写测试的想法,但与调试实际代码相比,我发现我花费大量时间尝试调试我的测试,以使他们说出我的意思。

在过去三年中,我一直在从事TDD的工作,而我的经验恰恰相反。如果没有编写单元测试,那么我花更少的时间来编写可以调试代码的单元测试。

我不仅要进行TDD,而且要由内而外地工作,即首先实现顶层/ GUI层TDD。实现顶层定义了系统中下一层的需求,我将使用TDD等开发该需求,直到实现该功能所需的所有代码为止。通常,当我实现了这样的功能并在实际系统中抽烟测试该功能后,我通常会第一次使用它。并非所有时间,但经常。

鉴于在实际系统中对功能进行烟雾测试所需的时间比执行几个单元测试所需的时间长得多,因此我节省了大量时间。对于我来说,使用TDD实现功能实际上比不完全不编写单元测试的功能要快。

但是编写单元测试是一项必须学习和掌握的技能,就像其他任何编程技能一样。当我开始进行TDD时,我有12年的编程专业经验,并且我是一个非常有成就的程序员。我认为为系统代码编写大型测试套件将是一件简单的事情。但是随着测试代码数量的增加,系统的不同部分发生变化以及必须对现有测试进行修改,我了解到构造和编写单元测试本身就是一种必须学习和掌握的技能。同样,并非所有代码都同样可以测试。系统代码必须非常松散地耦合才能有效地进行测试。实际上,学习TDD已帮助我使系统代码更松散地耦合在一起。

但是我目前在工作TDD方面的效率来自于既掌握如何编写单元测试的方法,又掌握了系统实现的技术(在本例中为C#)的结合。

在学习新技术的同时进行TDD可能很困难,例如,尽管我一直在做一些iPhone编程,但我没有编写大量的单元测试,因为我不掌握语言,目标c,也不掌握图书馆。因此,我不知道如何构建单元测试,甚至不知道如何构建系统代码以及如何使其可测试。

但是在实际项目中效果如何?

在最近几年我从事的项目中,尽管要求单元测试应充分覆盖代码,但我是团队中唯一编写测试的人。但是大型测试套件确实使我对能够重构系统充满信心,并且相信如果测试套件通过,系统将能够正常运行。

但是不幸的是,由于许多测试是在系统代码之后编写的,所以很多测试本身都是错误的,即它们并未真正测试要测试的内容。无法避免这种恕我直言。每次编写一段代码时,都有可能代码无法按预期工作,即存在错误。测试代码也是如此。因此,即使应该测试的代码未按预期工作,您仍有可能编写通过的测试。

首先编写测试,不仅在执行系统代码之前验证您是否失败了测试,而且还验证您是否完全按照预期的错误消息进行测试,从而大大降低了单元测试代码中存在错误的风险。

综上所述,以我的经验,一旦您掌握了TDD的艺术,就不会从长远来看节省时间,而且会节省很多时间。但是,即使是有经验的程序员,也需要花费时间来掌握TDD的技术。一支技能各异的开发人员团队甚至需要更长的时间才能掌握TDD的技术。


9

我们从中受益匪浅。

我们是一级商家,这意味着我们每年处理超过600万笔付款交易。

我们的支付网关系统具有数千个单元测试和集成测试。这些测试使我们对处理付款的能力充满信心。您想对自己的汽车制动器起作用充满信心,不是吗?我们希望有信心不会因为无法处理付款而失去业务。

代码覆盖使您充满信心。当然,仅靠它本身还不够,但这是一个很好的开始。

我们大多数的支付网关系统都是使用TDD编写的。有些方面很难测试,因此我们决定通过牺牲一些代码覆盖率来偷工减料。我们将尽快回来解决这些问题。

就个人而言,我发现在编写测试之前很难编写任何逻辑。话虽如此,我花了一些时间才开始以TDD方式思考。

Visa PCI参考:http//usa.visa.com/merchants/risk_management/cisp_merchants.html


3
“我们将回过头来最终解决这些问题。” -可能不会...除非他们用某些可怕的虫子给你打巴掌,否则不会。这些区域将成为其他所有内容的骨干,并指导所有设计的发展,因为没有人愿意投入资源来重做它们,也没有人愿意强迫进行任何可能会造成不良影响的更改。每次发生:P
爱德华·斯特兰奇

您正在猜测,当我告诉您公司内部正在发生什么时。提交后,我们可以提交代码覆盖率为70%的代码。CI主管不断增加这一点。在几个月内,最小代码覆盖率阈值将增加一小部分。之后,别无选择,只能进行更多测试。
CodeART 2012年

7

尽管某些人可能经常认为测试只是做太多事情的一种方式,但我确实认为在某些情况下这样做确实值得。

我已经为学校开发了Killer Sudoku Solver大约3个月,它使用许多“策略”来消除可能性和解决方案。事实是,可能性中的错误可能是致命的,并导致解决数独问题,因为当消除了某种可能性后,您就不再尝试了,如果是解决方法,程序将无法解决网格了。

但是,手动测试真的很困难,我的意思是说有一个网格,我可以看到在实际示例中哪些策略正在做什么,但是我不能每次都应用一个策略就检查所有方法,因为这代表了太多的数据。

而且,应用于特定网格的策略相当“随机”,也就是说,您不会在特定网格上使用全部策略。

因此,我只使用简单的情况(例如,只有两个单元已经消除了可能性)就每种策略编写了测试,检查了每个单元的结果,但是不幸的是,当我不幸遇到了无法解决的网格时,它每天为我节省了几个小时。因为我已经知道问题出在哪里。


2
我觉得这个问题首先在测试上投入更多,后来实施策略。测试对于调试应用程序当然很有用,在这些应用程序中,您自己测试每种可能性都很繁琐。
亚历克斯·希望·奥康纳

6

TDD的优点是您可以在编写实际代码之前先弄清楚如何调用代码。

换句话说,TDD可帮助您设计API。

以我的经验,这会产生更好的API,从而提供更好的代码。


编辑:正如我所写,这是“以我的经验”,即编写“现实世界的项目”时,但不幸的是,这是封闭的源代码,我无法让世界看到。从评论中我可以理解,这实际上是需要的,而不仅仅是对此类项目的存在的确认。

根据我的个人经验,我还发现,当您进入维护模式时,真正的好处就会显示出来,因为需求会不断变化。更加简洁的API使得在测试代码中表达新的或变更的需求变得更加容易,并且所有测试都使将来的维护者容易看到如何调用代码以及可以期待什么。

测试用例正在运行该规范的版本,使您可以非常轻松地了解如何调用API。这可能是到目前为止我所见过的“ HOW”-文档的最有用的一种形式(与JavaDoc之类的“ WHY”-文档比较),因为您确定它是正确的(否则测试将失败)。

最近,我不得不维护一个具有大量选项的可编写脚本的ftp客户端,这些选项都会影响应用程序的工作方式。最近为新功能引入了TDD,大型测试套件使我们能够进行修补程序,同时确信所使用的功能仍可以按预期运行。换句话说,这种过渡很快就会得到回报。


8
这个问题似乎完全是一个问题,因为这个问题需要真实的例子。但是由于三个人认为“这个答案很有用”,所以我一定会错过一些东西。

3
同意,但我缺乏拒绝投票的声誉。这只是“ TDD提供更好的结果”,而没有维护中TDD派生项目的示例来备份我想避免的答案。
詹姆斯

既然有几个人同意我的意见,我就敢投票。任何支持者或作者,请加强并告诉我们为什么这是一个很好的答案?

@delnan“我敢拒绝”-一个有趣的单词选择。编辑是否符合您的口味?

是的,现在我注意到了,就删除了我的弃权票。

5

一种特定的测试方法的价值取决于在开发中的系统对任务的关键程度,以及对它的依赖程度。您的网站的简单留言簿脚本几乎不被认为是关键任务,但是如果它运行的网站可能被允许对数据库进行未经过滤的输入的错误所破坏,并且该网站提供了一些重要的服务,那么它突然变得越来越重要了。对于彻底测试留言簿脚本很重要。框架/库代码也是如此。如果您开发的框架带有错误,那么使用该框架功能的每个应用程序也将具有相同的错误。

测试驱动的开发为您提供了额外的安全性。如果您在要测试的代码旁边甚至在测试之后编写测试,则很可能会导致测试错误。如果首先编写所有测试,则代码内部的工作方式不会影响编写测试的目的,因此,不太可能无意中编写了认为特定错误输出正确的测试。

测试驱动的开发还鼓励您的开发人员编写易于测试的代码,因为他们不想给自己做更多的工作!易于测试的代码往往是易于理解,重用和维护的代码。

维护是您真正获得TDD回报的地方。花费在软件上的绝大多数编程工作都与维护相关。这意味着需要更改实时代码,使其具有新功能,修复错误或使其适应新情况。进行此类更改时,您要确保所做的更改具有所需的效果,更重要的是,它们不会产生意想不到的效果。如果您有完整的代码测试套件,那么很容易验证所做的任何更改都不会破坏其他功能,如果所做的更改确实破坏了其他功能,则可以快速找到原因。好处是长期的。

您在问题中说了以下内容:

我看到为某些事情编写测试有一些好处,但很少。尽管我喜欢首先编写测试的想法,但与调试实际代码相比,我发现我花费大量时间尝试调试我的测试,以使他们说出我的意思。这可能是因为测试代码通常比其测试的代码复杂得多。我希望这只是对可用工具(本例中为rspec)的经验不足。

这似乎向我暗示您还没有得到测试。单元测试应该非常简单,只需一系列方法调用,然后是一个断言即可将预期结果与实际结果进行比较。它们之所以简单,是因为测试中的错误是灾难性的,并且如果在测试中引入循环,分支或其他程序抛出控制,则测试中很可能引入了错误。如果您花费大量时间调试测试,则表明您的测试过于复杂,应该简化测试。

如果不能简化测试,那么仅凭这一事实就说明被测代码存在问题。例如,如果您的类的方法很长,具有很多if / elseif / else或switch语句的方法,或者大量的方法具有由类的当前状态决定的复杂的交互,那么测试将必须非常复杂提供完整的代码覆盖范围并测试所有可能性。如果您的班级具有对其他班级的硬编码依赖关系,那么这将再次增加您为了有效测试您的代码而必须跳的步数。

如果您使用较小的方法,很少的执行路径来使类较小且高度集中,并尝试消除内部状态,则可以简化测试。这就是问题的症结所在。好的代码本来就很容易测试。如果代码不容易测试,则可能是有问题。

从长远来看,编写单元测试对您有好处,而避免它们只是在以后存储麻烦。您可能不熟悉技术债务的概念,但是它的工作原理很像金融债务。不编写测试,不注释代码,不编写硬编码的依赖项,等等都是使债务陷入困境的方法。您可以通过尽早地偷工减料来“借”时间,这可能会帮助您按时完成工作,但是您在项目中较早节省的时间却是借来的。每天都在不清理代码,对代码进行正确注释或构建测试套件的情况下,您可能会产生兴趣。持续的时间越长,积累的兴趣就越多。最终,您会发现您的代码变得混乱不堪,如果不触发意外后果就无法进行更改。

您可以考虑及早编写单元测试,并使其保持最新状态,这是“技术信用”的一种形式。您要花时间在银行中,因为要在项目的早期花时间遵循良好的实践。稍后进入项目维护阶段时,您将对这种远见卓识产生兴趣。当您要进行更改时,可以轻松地验证更改的正确性,并且它没有任何有害的副作用,并且您可以迅速获得更新,而不必大惊小怪。如果出现错误,则可以添加一个新的单元测试来执行该错误,然后在代码中修复该错误。下次运行单元测试时,您将能够验证该错误已修复,并且没有引起任何其他问题。此外,您将避免“回归”,

TL:DR-是的,它们是现实世界中的帮助,但它们是投资。好处直到后来才变得明显。


1
几个月前,我接受了这种逻辑。我喜欢TDD背后的想法,但发现它的现实有些令人不安。另外,我注意到即使在这里,也没有实际的例子可以继承基于TDD的项目。您是否真的回到了具有大量单元测试的旧代码库,并且获得了回报。
詹姆斯

遗憾的是,因为似乎没有其他人构建单元测试,至少没有在我从先前开发人员继承的任何代码上构建单元测试。如果有的话,我的生活将变得容易得多。我建议您在链接中查看该书,该书中有真实的示例,尽管它是针对PHP而不是Rails的。 amazon.com/...
GordonM

我是一般用途的忠实批评者,但对于在嵌入式或关键金融系统中使用这种方法的任何人,我都不会指责。
Erik Reppen 2013年

4

我在工作中经常使用TDD。我的经验是,TDD证明了自己的理由,因为您无需付出额外的时间或精力,就可以节省下来。

  • 由于我使用TDD,因此我花费的时间要少得多,因此无法进行调试。它只是从一开始就起作用,因为只要测试不通过,我就不会考虑编写高效的代码。

  • 质量检查报告的错误少得多,因此,在版本发布后,我们节省了修复代码的成本。这是因为TDD不允许您在没有测试的情况下编写代码,因此代码覆盖率要好得多。

  • 因为我不需要启动整个应用程序服务器,所以我可以更频繁,更快捷地运行(生产)代码。启动单元测试要快一个数量级。当然,只有当我想尝试生产性代码时,当测试已经可以执行时,我才能从中受益。以后进行测试时,将失去这种好处。

  • 我少做手动测试。不练习TDD的同事花大量时间单击应用程序,直到到达执行新代码的地步。在提交版本控制之前,我只手动测试一次。

  • 即使使用调试器,调试测试的执行也要比整个应用程序快得多。

也许您将单元测试视为回归测试。这是它们的目的之一,但是将它们理解发展工具会使它们更有价值。


质量是免费的!
MathAttack 2012年

2
质量差很贵!
沃尔夫冈

3

当客户验收测试人员或(禁止使用)生产用户发现错误时,另一个优点(除了已回答的其他人提到的优点之外)会发挥作用。将错误报告转换为针对似乎有问题的类的TDD风格的测试。观看失败。修理它。看着它过去。然后,您知道已经解决了该错误。这种技术节省了我几个小时。


2

好吧,我知道我个人会比其他开发人员快两倍,并且因为他们不做TDD而编写的错误少于一半,因此我从中受益。甚至应该比我更好的人...我的表现至少比他们强2倍。

我没有马上到那儿。我非常擅长编写代码,没有任何约束。写所有这些多余的废话似乎是一大浪费。但这可以做几件事,包括(但不限于):

  • 强制设计去耦和重用(在单元测试中必须重用所有内容)。
  • 提供了一个平台来开发小块和模块的代码,因此在运行简单的“甚至编译并接受输入”类型的测试之前,我不必弄清一切并完成所有工作。
  • 提供一个快速的测试平台,以便在人们要求我没有想到的功能更改时进行更改。

后来的一个例子是我目前正在处理的一个项目,潜在客户突然决定完全重写它使用的通信协议,原因几乎是0。我已经将其与其他所有功能脱钩,因此能够在2小时内对更改做出响应,并且能够完全独立地进行处理,直到最后将其绑定在一起并集成了测试步骤。我的大多数同事可能会待上一天或更长时间,因为他们的代码不会被解耦,而且他们会在这里,那里,到处都在更改...全部编译...集成测试...重复,重复那样花的时间要长得多,而且远没有那么稳定。


2

答案是肯定的。在我公司,我们已经开发C ++应用程序已有20多年了。去年,我们在一些新模块中加入了TDD,缺陷率显着下降。我们非常喜欢它,以至于我们每当在其中更改某些内容时,甚至有些人就在旧代码中添加测试。

此外,整个模块从头到尾完成了整个生产过程,并且从未演示过错误(这也是关键模块)。因此,它的开发比平常更快,因为通常会发生其他情况,即模块将“完成”,仅从Beta测试返回4-5次以修复错误。这是一个重大的改进,开发人员也对新过程感到更加满意。

我没有做过很多Rails TDD,但是我在C ++,C#,Java和Python中做了很多工作。我可以告诉你,它绝对有效。我的猜测是您因为没有足够的信心而花大量时间思考测试名称。首先编写您的测试,但要让您的创造力流动...

我注意到,一旦您真正掌握了TDD的窍门,您就会开始不太在意“我将如何命名此测试... argh!”,然后您就可以顺其自然地进行重构和改编已编写的内容。测试以适应当前情况。

小费时间

提示1

因此,我认为最能帮助您的窍门是不必担心太多。关于TDD的最漂亮的事情之一是,它使您有勇气更改已编写和正在工作的内容。包括测试。

提示2

通过一个简单的“ canCreate”测试开始新的类测试,只是为了使您的思维朝着正确的方向发展,就像“好吧,我现在正在上这堂课……对。”

然后开始添加更多的测试,一次只能添加一个,并确保您创建的每个测试都是您想到的下一个最简单的情况(考虑不超过30秒,然后超时)达到最佳效果)。

并记住

不必担心重构现有测试,甚至不必删除过时或多余的测试。很少有人意识到这一点,但是在TDD中,您实际上以1的价格获得了2个安全网。您的测试是用于更改生产代码的安全网,但是您的生产代码也是用于重构测试的安全网。这种关系是相互的。实际上,这是紧密耦合的一个好例子。

再试一下。并且让我推荐观看Clean Code Casts,尤其是有关TDD的那些。


1

现实世界中的重要例子:

我必须编写一个数据结构转换函数。输入将是一个数据结构(实际上是一个嵌套的数据结构,很像一棵树),而输出将是一个类似的数据结构。我无法想象出真正的转变。TDD的主要好处之一(无论如何对我而言)是如果您不知道如何执行婴儿步骤(请参阅Kent Becks的“ TDD示例”)。因为我不知道要怎么做,所以我从简单的基本案例开始,例如空的或琐碎的输入,然后一直处理到更复杂的案例,直到我发现所有案例都涵盖了。最后,我有了一个有效的算法,并通过测试证明了这一点。这些测试不仅证明我的实现现在正在起作用,而且还使我免于日后搞砸。


-1

我不喜欢盲目地遵循任何通用建议的想法,因为我不认为有一种千篇一律的建议可以帮助大多数开发人员提高生产率并减少应用程序中的缺陷。根据我的经验,对质量的担心越多,所交付的新功能的损失就越大。因此,您要对质量与可交付性给予重视的程度实际上取决于您的产品和当前策略,并且很可能将由其他人暂时决定战略上更重要的是:坚固性或可交付性。

即使这个决定也不是黑人或白人。您的应用程序的某些部分很可能必须健壮,而其他部分则不必。一旦确定了哪些零件应具有较高的质量,就应该从测试的角度来关注它们,因为您要确保这些零件的高质量。

到目前为止,我所说的所有内容都与TDD无关,特别是在实现之前编写测试的意义上,但是我认为,将经过测试的代码与首先编写测试的好处区分开来是很重要的。

一旦了解了测试本身(不论是否为TDD)的好处,就可以讨论要包含在测试中的代码的测试策略。有人会争辩说,如果您以后编写测试,则会错过测试中的某些条件,但是我认为您应该是一个评估是否适用于您的人。这当然不适用于我。

所以,这就是它对我的作用。基本上有两种情况会让我编写测试:它只会提高质量,或者也会加快我开发某些功能的速度。因此,在待办事项中没有新功能的情况下,我将编写测试,然后我可以决定提高应用程序的性能,简化代码库或改进测试套件。另一种情况是需要有一个可靠的工作代码,其中的错误会对真正的客户产生足够大的影响。还有一个用于测试复杂代码,该代码在使用时很容易被破坏。举例来说,我的代码库中有一个QueryBuilder类,它处理许多用例,并且在修复错误或添加新功能时很容易破坏其中一些用例。

最后,在某些情况下,编写测试首先使我能够更快地编写功能,然后根本不编写测试。QueryBuilder也是这种规则也适用的情况,但这并不意味着TDD也是最佳途径。TDD有助于提高开发速度的另一个示例是例如测试Excel生成,而在实际应用程序中,每次要测试生成中的某些特定条件时,您可能必须执行几个步骤。或者,如果您需要创建一些记录以测试功能,那么在手动测试代码后很难或无法手动删除它们。

因此,如果您更容易重现以编程方式(通过测试)运行某些开发中代码的步骤,请继续使用。但是,如果编写测试比较复杂,然后手动进行测试,那么您就必须决定是时候关注质量,还是在积压中有很多请求,公司中的某人可能会更好地了解它,并让您知道您应该根据他们当前的需求和公司策略关注的重点。

在理想的世界中,所有代码都经过测试,但是不能假装没有权衡取舍,并假定TDD始终是最佳且唯一的途径。与现有的所有最佳做法一样,您必须始终专注于对您工作的公司最有利的事情,而不是对您更有利的事情。一旦成为个体经营者,如果您认为这是最好的方法,则可以随时决定执行TDD。如果您的公司认为应该对所有代码进行测试,那么您必须为所编写的所有代码编写测试。但是对于大多数情况,在做出任何决定之前,您必须了解全局并了解取舍。抱歉,但这并不是一门精确的科学,没有每次都应遵循的简单(或艰难)的“一刀切”的答案。

与设计模式相同。了解它们的工作方式以及创建它们的原因,解决它们什么样的问题以及它们的缺点。理解推理比记住拟议的解决方案更为重要。今天,使用其他技术可以轻松实现当今昂贵的操作。如果某个状态良好的解决方案的前提不再有效,那么该解决方案将不再是最佳的解决方案。当需求,可用技术或公司策略发生变化时,您应该始终重新评估工具箱,并且在发生这种情况时,您需要了解为什么首先选择每条路径,而不是将它们视为最佳选择。


这甚至都没有试图回答所问的问题:“我们最终有没有任何例子表明收益是真实的?有人真的继承或返回了使用TDD设计/开发的代码,并具有完整的单元测试集吗?真的有收获吗?”
t 2014年

1
它可以回答,但是由于您不同意我的看法,因此您给-1 :)基本上,任何不尝试显示TDD值的人都会从您的角度给出不想要的答案;)让我猜。您是TDD传播者,对吗?:)顺便说一句,作者真正的问题是TDD是否还清。您不必练习TDD即可回答。Fortran编写Web应用程序是否有回报?在回答之前,您是否尝试过?
罗森菲尔德2014年

我对TDD没有意见,也不会以喜欢/不喜欢的方式使用投票(这是一个问答网站,而不是Facebook)。根据我的阅读,这个“答案”根本没有正面或负面地解决所提出的问题
2014年

在我看来,这不是一个技术问题,例如“如何使用nginx进行X?”。当作者实际上想了解其他人对TDD的看法以及它是否值得时,对于这样的问题有正确的答案,但对于这样的定性和主观问题则没有正确的答案。那是我试图表达我的观点。我不知道答案如何才是正确的答案,因为在我看来,所有答案都像是个人观点。您无法有效地衡量TDD是否值得。任何试图这样做的文章从根本上都是错误的。
罗森菲尔德2014年

“这个网站是所有游览的 答案。这不是一个讨论论坛...”
t
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.