兄弟,你到底有没有做过单元测试啊?
单元测试是火箭科学
单元测试是火箭科学
很多程序员都不写单元测试。主要原因是他们不明白为什么要花时间做这个。他们觉得这纯粹是浪费时间,对吧?
我以前也是这样,后来我的代码开始在生产环境中崩溃,而且是在一些大型且备受瞩目的项目中。所以,我开始寻找方法,让自己对自己的代码和提交更有信心。
单元测试是第一个答案,但我花了一段时间才正确地编写出来。
什么是好的单元测试?
要编写一个优秀、可靠且值得信赖的单元测试,你需要:
-
理解你要测试的内容。这听起来可能很傻或者很明显,但事实并非如此。阅读方法,理解它的作用、方式和原因。如果你不知道它应该做什么或不应该做什么,又如何测试它呢?
-
避免过度使用模拟对象。模拟对象虽然能让编写测试变得容易,但并非最佳实践。只有在别无选择的情况下才使用模拟对象,例如用于 API 调用。而且,请不要对被测类进行桩化!
-
SEAT。设置、练习、断言、拆卸。对每个测试重复此操作。
-
I/O。专注于数据转换。定义初始状态,运行测试,断言输出结果。过程中发生了什么,或者它是如何发生的,都与你无关。
-
确定测试范围并坚持执行。一个方法可以包含任意数量的测试,但尽量将测试按用例场景分开。
你想断言一个方法能够将数组转换为 JSON,并且抛出异常?没问题,那就写两个独立的测试!
代码覆盖率真的重要吗?
简而言之:不,并非如此。
我听很多人说应该追求 100% 的代码覆盖率。但这其实是个坏主意。
别误会,代码覆盖率越高越好。但这不应该是你的主要关注点,也不应该是你的目标。
在为某个方法编写测试之前,我会问自己几个问题:
- 该方法是否会转换数据?
- 我可以在不模拟方法输出的情况下编写这个测试吗?
- 该方法是否返回任何值?
- 我可以对结果做出断言吗?
如果这些问题中任何一个的答案是否定的,那我可能就不会出题了。
代码覆盖率达到 100% 并不代表代码就经过了充分测试。
你不可以过去 !
代码由公共方法组成,没错,但也包含私有方法和受保护的方法。
我们应该对它们进行测试吗?
当然不是。但某种程度上来说,是的!
它们通常包含业务逻辑,所以,是的,需要测试它们。但是,与公共方法不同,私有方法不需要专门的测试。
私有方法的目的是被同一个类的公共方法调用。让我们在测试中应用同样的逻辑。私有方法和受保护方法应该通过公共方法的测试来进行测试。
永远做第一
我习惯于按照 FIRST 原则编写测试,但还有其他方法,例如 AAC。
我假设作为一名开发人员,如果 FIRST 不适合你,你知道如何使用 Google 找到其他方法!
-
速度:测试应该轻量级且速度极快。否则,我会劝阻你或你的团队不要运行它。大型项目可能包含成千上万个测试和断言。
设置、测试和清理工作都不应该超过几毫秒。 -
独立性:测试之间不得相互依赖,也不得依赖于先前测试的状态。
所有所需数据都应在当前测试中创建,并在测试结束后销毁。
如果多个测试需要相同的数据,只需在设置过程中创建即可。 -
可重复性:测试应该能够反复执行。时间、日期或时区不应影响测试结果。
没错,你可以扮演时间领主,模拟时间(当然,除非时间点是固定的 ;-))。
记住,如果测试失败,唯一合理的理由应该是方法没有按预期工作,或者测试本身有误。好了,就这些! -
自验证:无需人工检查即可确认测试是否通过或失败。
-
认真细致:不要偷懒。编写单元测试需要时间,有时甚至比编写方法本身还要花时间。
- 测试每个使用场景
- 不要局限于简单的价值观,要追求边缘价值观。
- 如果这些方法能够处理批量数据,请使用大型数据集进行测试。
- 异常和错误测试
- 不要只测试成功。你还可以断言失败,而且你应该这样做!
结论
保持测试的简洁性,将其限制在特定的范围内,并专注于方法的输出。
单元测试只是完整测试周期的第一步。请看下面的金字塔图。
文章来源:https://dev.to/juyn/do-you-even-unit-test-bro-434g



