为什么事后测试是一种不好的做法

2025-05-25

为什么事后测试是一种不好的做法

在这篇文章中,我将尝试向您提供我的观点,说明为什么在拥有所谓的“工作”代码之后再编写测试是一种不好的做法,以及为什么您应该避免这种做法并努力先进行测试(也称为 - TDD)。

一些背景

就这样,您的功能就完成了,而且确实可以工作!

嗯,至少就你手动检查过的情况而言。它涉及几十个文件,几个是新文件,几个是修改过的旧文件,但你对自己的成果相当自豪。

你查看了你的 Jira 板(或者你最近的毒药),看到那张票上写着“为其编写测试”,于是你拿起咖啡杯,开始用一些断言来弄脏你的手。

你根本不懂 TDD 和先写测试有什么大不了的。你这样写代码已经好几年了,看起来一切都运行良好。我的意思是,每段代码都有 bug,对吧?而且你的代码有时很难引入新功能……或者,可能你觉得新功能引入太频繁了?还有,那些充斥着 mock 的测试,莫名其妙地就变得太复杂了……嗯……

那种让你感到不安、脊椎发软的感觉确实存在。

以下是关于编写测试后如何导致我上面提到的症状的几点:

无意识地遵循既定的“现实”

这是我们的人性——当遇到某种情况时,我们会试图去适应它,甚至为错误辩解。

我们的代码是一个既定的“现实”。它就在那里,并且能够正常工作(就我们所知)。你现在编写的测试将倾向于建立并支持你所创建的现有现实。
它会通过遍历代码中涵盖的路径来实现这一点,它会更频繁地关注成功路径,并且会成为陷阱。测试后通常会产生较差的代码覆盖率,这并不奇怪。由于我们希望遵循既有的原则,我们更容易忽略某些情况。

以常见的“加法”函数为例——在代码实现后编写测试时,你会尝试添加几个数字,并观察它是否按照你记忆中代码应该的方式工作。但如果你先编写测试,你就会开始思考函数如何处理没有收到预期参数的情况,这些参数既不是数字也不是类型。

从这个意义上讲,TDD 在某种程度上迫使你在编写实际代码之前考虑边缘情况。很多情况下,事实证明,这样做可以生成更具弹性的代码。

对我们的代码的情感依恋

我们对工作怀有深厚的感情。每当你提交 PR 并被要求修改某些内容时,你都能感受到这一点。承认自己所做的某些事情需要修改需要很大的自律性,而且很多时候,人们会为了些小问题争论很久。审视一下你的感受,你就会知道这是真的。

你可能会问:“事后测试跟这有什么关系?”
测试往往会暴露代码设计的缺陷。当你的代码过于复杂或耦合度过高时,事后编写测试会暴露出糟糕的设计。
尽管测试表明设计存在问题,但你会发现许多人选择忽略这些红灯,不去重构代码,却不知何故让测试因缺乏可测试性而受到影响。

这可能表现为缺乏测试、忽略某些用例以及过度模拟。
实践 TDD 有助于避免此类情况,并帮助我们更好地设计代码。TDD 默认会提高代码的可测试性,而具有良好可测试性的代码也更灵活,更容易修改。

过度嘲讽

实践 test-after 通常会生成需要更多 mocking 的测试。这种情况意味着你的代码与一些本不该紧密耦合的模块紧密耦合,或者代码的关注点分离 (SoC) 不足。当你编写代码时,没有什么能阻止你紧密耦合,但现在测试暴露了这一点。

过度模拟意味着你的测试变得更加复杂,可读性也更差。此外,在某些测试框架中,它可能会导致运行器过载。

您可能知道,模拟也需要得到良好的维护 - 您需要清理它、恢复它、应用它,而当您试图弄清楚为什么某个测试没有通过时,这可能会非常令人沮丧,却发现您忘记恢复模拟了。

最后被忽视

一开始我就说你有那张“为它写测试”的 Jira ticket。我不明白你当时为什么不打断我 :D

我要强调的是,你不应该收到这样的工单。编写测试并非一项额外的任务,而是功能开发任务中不可或缺的一部分。而且,当你把它拖到最后时,在产品团队看来,这是最容易被推迟到“永远”的任务——毕竟,在他们看来,这个功能已经“运行”并且完成了。

有时开发人员只会编写没有价值的虚拟测试,但不知何故会增加代码覆盖率,这甚至比根本不编写测试更糟糕,因为它给人一种错误的感觉,即代码已被很好地覆盖和保护,而实际上并非如此。

总结

如果我们更多地实践 TDD,我们每天遇到的许多编码问题都可以避免。我并不是说这种转变应该是二元的,或者这样或那样的,但我希望我在这里写的内容能帮助你更加坚持(即使在你内心深处与自己争论的时候)你想要编写的代码的质量。

我知道现实有时要求我们尽快写出代码,但作为专业人士,我们应该始终努力使我们的工作变得更好,并在工作中不断进步。

你同意吗?跟我们分享一下你的想法吧 :)

嘿!如果你喜欢刚才读到的内容,可以在推特上关注@mattibarzeev 🍻

照片由Jennifer BedoyaUnsplash上拍摄

文章来源:https://dev.to/mbarzeev/why-testing-after-is-a-bad-practice-2pj5
PREV
React Hook 数据抓取 问题 useFetch Hook 深入探讨 Connect
NEXT
使用 TDD 创建 React 组件