我应该使用TDD吗?

40

我在我的(非常小的)公司是唯一的开发人员,即将开始为该公司开发一个中型 ASP.NET 网络应用程序。

我正在考虑是否应该学习测试驱动开发(TDD)并在此应用程序中实施它。

我需要尽快开始开发我们的新应用程序,但我担心测试问题。我已经编程多年,但从未进行过任何单元测试。

我已经阅读了很多关于 TDD 的在线资源,但我不确定我是否有足够好的掌握它以使其在应用程序中有效。

15个回答

41

这取决于你的优先事项。如果你想成为一名更好的开发者,TDD绝对值得学习,即使只是为了体验。它将帮助你重新思考编码方式,并因此成为更好的开发者。

但是,TDD可能会严重影响你及时完成产品的能力,这可能会让你的优点被抵消。你提到你是公司唯一的开发人员,这意味着你必须承受完成项目的压力。TDD确实是一个很好的实践,但有时现实约束和实用性必须放在第一位。

简而言之,如果你有时间,那么使用TDD是可以的。它实际上并不需要太多的额外工作量,而且在紧急情况下你总是可以跳过测试。但是,如果你真的时间紧迫,而且认为没有将其纳入计划中会让你的产品和工作处于风险之中,那么没有人会责怪你跳过它。纯粹主义者会持不同意见,但这不是非黑即白的世界,有时必须做出妥协才能完成任务。


3
TDD非常适合于库程序例程,比如字符串操作或日期处理等,这些程序必须按预期工作,并且可以保持简洁。 - Thorbjørn Ravn Andersen
考虑好TDD项目的好处非常重要。它可以提高您开发出高质量、可维护、复杂产品的能力。它还可以让您作为开发人员超越自我,直接影响产品的可维护性和敏捷性。它为项目增加了价值,并且随着时间的推移,可以使修复/增强变得更快更容易。 - DaFi4

25

记住这一点: 唯一不好的测试是你没有执行的测试。

现在,你需要直接进入TDD吗?也许不需要。但你应该确实开始对任何可以进行单元测试的内容进行测试。你不能很好地对GUI进行单元测试,这没关系 - 把它们留给UAT测试。

但是,任何可能在后台执行的逻辑,都应该进行测试。

首先尝试测试单个方法。随着不断的尝试,你会遇到困难,因为很可能你的代码并不是为了测试而设计的。这没关系;重构你的代码!一直这样做,直到你可以测试你的代码。记住你所做的事情,并在下次编写代码时第一时间采用这种方法。

经过几次迭代,你会学到你需要学习的东西(真的,只有通过实践才能学到),痛苦就会消失。 当这种情况发生时,我建议你已经准备好研究TDD了。


5
+1:就去做吧。"不会学好"是一种通过在开始之前要求“足够好”来阻碍进步的方式。现在就开始吧! - S.Lott
2
记住这一点:唯一的坏测试是你没有执行的测试。 这让我想起了http://www.youtube.com/watch?v=l1wKO3rID9g :) - Surya
1
好的观点。我想我只需要去做并看看结果如何。那确实是学习某事的唯一方式。谢谢。 - CalebHC
4
我不同意“唯一坏的测试是你没有执行的测试”这种说法。也许更糟糕的测试是那些看起来在测试某些东西,但实际上却没有测试到,从而给人一种虚假的安全感。另一种糟糕的测试是测试基础架构而不是你的代码——比如,测试当我向一个整数变量赋值时,赋值是否正确完成了。 - JeffH
只有通过实践,你才能掌握TDD。你花费的时间越多,就会变得越好。一开始你可能会感到非常缓慢,但随着你的不断实践,你会变得更加熟练。 - Spock
过多的低质量测试会在复杂项目中使自动化测试变得过于缓慢,但我仍然很难划定那条线。也许一些新的自动化测试产品可以提供测试结果历史记录报告,以帮助我后续工作。 - DaFi4

14

我无法强调采用TDD开发方法的优点。当您采用TDD时,您的单元测试成为您编写的代码的头等公民,而不是仅为拥有单元测试而维护的代码,也不会因为没有及时更新而被抛置不顾。

在TDD中,您将使用您的单元测试作为组件应该执行的可执行规范。为此,可以考虑您希望组件执行的功能,然后编写测试来执行此功能。由于您的代码最初不具备任何此功能,因此您编写的所有新测试都将失败或呈红色。一旦您编写了测试,请开始实现组件。随着逐步添加所需功能,红色测试将变为绿色。美好的事情是,在实现足够的功能以使所有测试都通过后,您知道已完成实现预期规范的工作,也知道应该在何处停止。我经常看到这样的情况,即开发人员已完成所需的功能但不停止,而是增强组件并添加额外的功能和华丽效果,这些都不是所需规范的一部分,浪费了积极的开发时间。

一旦您拥有了单元测试,就可以轻松地在持续集成环境中设置它。该环境将从您的存储库中检出最新代码,构建它,然后运行您的单元测试。如果发生任何回归,即如果有人提交了破坏您的单元测试的代码,您将立即得知,而不是在部署到生产环境后才发现。为确保新代码不会引入回归,我们已在存储库上设置了登录挂钩,以确保所有提交的代码也已运行相应的测试并通过了测试。当多个人共同工作于一个项目时,这尤其有帮助,因为他们可以通过您可能使用的任何监控仪表板看到存储库在该时间点是否可同步。找到当前正在破坏构建的问题的人修复该问题时,很容易定位存储库的特定版本,让其他人使用已知的良好版本进行工作。这也可能意味着仪表板指示的任何“绿色”构建都具有非常大的概率在推送到生产环境时不会遇到问题。

许多人认为采用TDD会增加额外的工作和麻烦,而且会更耗费时间。但是请考虑一下,编写测试所花费的额外时间将防止正在测试的任何功能出现故障,并且您会更早地发现这些故障。
使用TDD的另一个优点是,您将更加关注设计,它将比非TDD方法更好地结构化和组件化。这种组件化对于能够快速执行并且不易出错的单元测试套件非常重要。
GUI测试很困难,但并非不可能。请考虑像Selenium、WebDriver和Watir这样的Web-UI测试技术,它们可以以编程方式操纵Web-UI。但是,过度依赖这些工具,只进行昂贵的端到端测试是很容易误用它们的。更好的方法是抽象出您的UI层,以便可以在业务逻辑之外单独测试它。
总之,您希望编写高效的单元测试,使TDD成为一种愉快的体验,而不是负担。您的测试应该快速,独立测试组件,最好全时运行。
我描述的是一种理想情况。您无需采用每个想法,但是可以挑选其中的一些,使您的开发流程更加高效。

10
请注意,TDD不是关于测试的;它是一个开发过程。测试并不是为了取代测试功能-它定义了开发过程。
听起来你在谈论单元测试和其他自动化测试。测试是好的。自动化测试也是好的。不要害怕犯错误。如果您考虑您的代码以及尽可能自动化测试,那么您处于一个良好的位置,但是存在收益递减的截止点。完全自动化测试可能不划算-特别是对于您所描述的组织而言。
如果您真的在谈论TDD(专家称之为TDD),那也是好的。有很多开发过程。记住,开发过程是框架和指南,而不是像追求一样遵循的宗教。没有一种过程适合所有人。根据自己的情况做出合理的改进。在dev组织中只有一个人使得更改流程相当轻松。首先解决高风险问题,并针对这些问题实施一些轻量级的流程,然后再着手解决低价值问题。

请注意,有证据表明TDD作为一种过程并不真正有用 - 成功可能是因为处于前沿的人无论使用什么过程或缺乏过程都会成功。 - Tim

6

最好的学习方法是实践。如果你已经读了这么多关于IT技术的内容,那现在是时候开始动手了——对于单个开发人员来说,拥有单元测试可以成为救命稻草,因为没有其他人能够审查你的代码。


4

我还是一名新手开发者,加入了一个已经在进行应用程序开发的公司。TDD帮助我确保新的更改不会破坏已经完成的工作,同时在我添加或修改代码时,它也有助于避免大量的错误调试。

我喜欢从中学到的所有知识,并强烈推荐花时间学习TDD。

-我的.02


是的!TDD还允许您将概念纳入其中,其中构建和测试会自动连续发生,因为检查了新代码!问题可以更早地被检测到,并且在您的同事度假之前! - DaFi4

4

只有一个开发人员实际上是相当小的开发工作量。即使您期望有很多屏幕,单个编码人员要达到中等规模仍需要很长时间(除非他们疯狂地剪切和粘贴)。

我不是TDD的忠实粉丝,但如果你是相对较新的程序员(少于10年),你自己做,并担心质量问题,我相信它既会减慢你的速度,也会帮助你提高工作质量。对于年轻的程序员来说,它迫使他们更专注于代码的真正基本行为,并逐步完成工作(一个早期的常见错误是过多地输入大量的代码,然后尝试一次性调试所有代码。老的编码人员可以得以摆脱,年轻的编码人员通常需要分阶段地进行工作)。粉丝经常说它彻底改变了他们编码的方式(通常使整体工作更容易)。至少你可以从这里开始,如果它没有真正帮助到你,可以随时放弃。

您最大的问题,TDD无法解决,那就是为Web应用程序获取良好的架构结构。一个您五个月内不想放弃的架构结构。Web应用程序可能非常棘手,很少有人在前十二次尝试中就能做得正确。


4

我最近开始在所有新代码中使用TDD。起初,它看起来只是浪费时间,因为我的逻辑与Gui紧密耦合,所以我无法编写任何真正能够保证我的代码执行正确的单元测试。
但是过了一段时间后,我意识到编写单元测试非常痛苦,因为代码写得很差。我开始以这样的方式重构代码,以便我可以编写有意义的单元测试。我开始缩短我的方法长度,更多地使用接口,并尽可能将逻辑与Gui分离。
我认为使用单元测试的目的除了测试和验证代码外,还包括使您成为一个更好的程序员。因此,不管怎样,学习它都是值得的。


3

我想总结并评论一下以上评论:

  1. 是的,TDD是关于设计的。它不是关于测试的。
  2. 不确定为什么QA会参与George的设计阶段。听起来他们在指定自动化测试。正如Tim所指出的,这是一个开发过程。
  3. Kevin,你说“跳过测试”。再说一遍。TDD关注的是设计,不是测试。好吧,你可以跳过设计,但最终的应用程序将存在漏洞且无法支持。
  4. Roshan提到,“组件应该做什么的可执行规范”。那意味着完全更新的文档。当你新加入一个项目时,你可以很快地了解情况,你可以看到原始开发者的具体意图。而且,正如Jon所提到的,你可以进行代码更改并确保没有任何问题。

2

Caleb - 我想向你推荐一个旨在帮助自学TDD的网站。如果你不受压力,你会更好地学习。只需在Google上搜索 "tdd-problems" 即可找到它。


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