我爱上测试驱动开发的 4 个理由。

2025-06-07

我爱上测试驱动开发的 4 个理由。

如果你有兴趣阅读西班牙语版的这篇文章,请查看我的博客《开发者的地牢》

直到两年前,我从未在专业环境中编写过单个单元测试,是的,你没听错,我很惭愧地承认这一点,但在我职业生涯的前三年,从来没有人要求我编写测试,我一点也不在乎。

我不知道它们是如何工作的,更不用说它们能带来的好处了。我当然知道它们的理论,也从博客上知道它们可能有用,但说实话,我并不认为它们重要。
后来我读了《代码整洁之道》和《程序员清洁之道》(罗伯特·C·马丁著),愧疚感油然而生。我意识到,在我的职业生涯中,我没有提供任何可重复的证据来证明我的软件是有效的,它确实是纯粹靠运气,而且只在非常特定的情况下才由我测试过。

我也意识到自己交付这样的产品是多么不负责任,不仅损害了软件用户的利益,也损害了我深爱的这门手艺。
我突然想起,很多时候,一些已经“完成”的代码部分会反复出现bug,一个无关的软件改动就可能导致大量已经手动测试并“修复”的问题。
我也明白了,在进行重构之前,我感到的是恐惧,深深的恐惧,因为一旦打开重构之门,我可能会犯下错误。


正是在那一刻,我决定站出来,为自己做出改变。正如 Michael Feathers 所说:“遗留代码就是没有测试的代码”。我承诺,我编写的任何代码都不会是遗留代码,因此我一定会进行测试。
我明白,除非你的代码有一套测试来证明它正确无误,否则开发就不算完成。从那时
起,在代码运行起来后,我就开始编写大量的单元测试,尽可能地覆盖所有可能出现的问题。当出现 bug 时,我会修复它,然后再为它编写单元测试。虽然我的代码质量和作为一名开发人员的自尊心都在提升,但我的恐惧却从未消失。
事实上,每次我不得不重构某个代码时,这种恐惧都会再次袭来,即使有大量的单元测试也无法阻止它。最糟糕的是,当发现 bug 时,一个单元测试应该已经捕获了它,但由于其他原因它却通过了,我对这个测试套件的信心就会急剧下降。很多次我回家后都会质疑做单元测试是否值得,或者我只是在自欺欺人。

后来我读了 Kent Beck 的《测试驱动开发实例》,一个新的可能性就此敲响。或许开发流程的顺序确实很重要,而“倒着做”反而能带来一些好处?于是我决定尝试一下。


一点背景:

TDD 是一种让测试指导解决方案设计的实践,遵循这一流程将使你的代码解耦且可测试。
通常,当我们想要开发一个新功能时,我们会立即投入代码,疯狂地敲代码,最终得出一个虽然很蹩脚但能用的解决方案,然后编写一个单元测试,就此结束。而 TDD 则将这一过程颠倒过来。

  1. 问问自己,你的软件应该做什么?在什么情况下它可能不起作用?然后你继续编写你的第一个测试来证明你的假设,这个测试显然会失败,因为还没有实现。
  2. 然后,您需要做尽可能最小、最简单的事情来让您的测试通过,只需专注于让灯变为绿色。
  3. 最后,当测试通过时,您重构您的实现并修复上一步中允许发生的所有“坏事”,但始终确保灯仍然是绿色的。

这个循环被称为“红绿重构”。

红绿重构

现在我们了解了基础知识,让我们来看看我爱上 TDD 的原因:

一见钟情

通过遵循这条路径,你总是从代码无法工作但你使其工作的阶段开始,这就是我喜欢 TDD 的第一个原因,信心

当您第一次看到您的代码和测试失败,但经过一些更改后使其通过时,您会立即获得满足感,这会增强您对实现的信心和信任,这是一个简单的变化,直到您面临强大的重构,然后您会发现您不再害怕,如果您破坏了某些东西,您的测试就会在那里保护您。

第二次约会

通常,当您必须开发新功能时,您必须接触现有代码,您会在这里和那里更改一些内容,但最终您会处于一个没有开发人员愿意去的地方,代码不再起作用,并且您做了很多更改,您不确定哪一个破坏了它,您花费大量时间尝试找到那个更改,或者有时您会回滚所有更改并从零开始。

面对这种情况,我发现了喜欢 TDD 的另一个原因:低风险。

在 TDD 期间,您处于非常短暂且快节奏的红绿重构周期中,每次运行都会以非常渐进的方式引入新的变化,因为代码在几秒钟前还在运行,所以找到导致灯变红的变化并修复它们很简单,这样我们就可以再次看到我们珍贵的绿灯。

第三次约会

很多时候,当我在代码完成后编写测试时,都会遇到一些会导致整个测试套件崩溃的错误。我发现,这是因为测试套件的基础从一开始就不稳定。
当你在写完实现之后再编写测试时,很常见的情况是,你的测试往往会无意识地只走“快乐之路”,也就是代码中所有东西都“绿色”、“漂亮”且“崭新”的地方,从而避开那些难以测试的测试用例,这仅仅是因为你的代码从一开始就不是为测试而构建的。

这种情况向我展示了第三个原因,即无惧极端。

TDD 迫使你首先考虑测试,有了这种思维方式,你就可以完全专注于边缘情况,通常会破坏软件的事情将被神奇地覆盖,你会发现在寻找这些边缘情况时有一种新的乐趣,并确保它们首先变红,但最终变绿。

同居

最后,这一点与上一点相关。当我第一次开始做测试时,我作为一名软件开发人员的工作成为了世界上最无聊和最繁琐的任务之一,我诅咒自己不编写测试的那一刻,这种无聊促使我避开那些很难测试的路径。但是,TDD 来拯救我了,通过先进行测试,看到它们失败,然后修复它们,我养成了上瘾的习惯,但“别担心”是一种好的习惯,我沉迷于在我的代码中查找错误并修复它们,确信这些错误不会再次出现在我的代码中,或者至少不会以同样的方式出现,这就是达成交易的原因,基本上 TDD 使单元测试变得有趣。


从那时起,我无法想象没有单元测试的开发人员生活会是什么样子,有时我甚至会为了重现错误而编写测试,而不是手动尝试。
我提到的这种爱好甚至促使我创建了一个 VSCODE 扩展,以便轻松运行 Angular 单元测试,从而跟上测试驱动开发的快速周期。

我真心希望读完这篇文章后,你能够对 TDD 产生兴趣。说实话,这条路确实很难走。我仍然需要时刻提醒自己,不要偏离计划,在应该编写下一个测试的时候继续执行。但随着实践的积累,这条路会变得容易得多,好处也会更加明显。

你说呢,你准备好跟我一起走这条路了吗?

文章来源:https://dev.to/patferraggi/4-reasons-i-fell-in-love-with-test-driven-development-25b4
PREV
申请所有工作,招聘信息无论如何都不现实。
NEXT
GitHub 使用 ruby​​、github-actions 和 dev.to API 自动 README