在更正错误时,我们是否应该始终对它们进行单元测试?


29

纠正错误时,鼓励我在这里工作,首先编写一个因给定错误而失败的测试,然后修复代码,直到测试通过。这遵循TDD惯例,应该被认为是很好的惯例,但是我注意到它往往会产生与实现非常接近的神秘测试。

例如,我们在发送作业,达到某个状态,中止并重试时遇到问题。为了重现此错误,编写了一个包含线程同步的大量测试,其中包含大量的模拟和其他东西。它确实可以完成工作,但是现在我正在重构代码,我发现删除此庞然大物非常诱人,因为要适应新设计,确实需要很多工作(再次)。它只是在单个特定情况下测试一个小功能。

因此,我的问题是:如何测试难以重现的错误?您如何避免创建测试实现的东西,并损害重构和可读性?


该错误情况与新设计有关吗?对我来说,新设计的一部分将是提高设计的可靠性,因此,如果这种类型的错误与原始设计中的错误有关,则您可以使用它来证明删除该测试用例是合理的。
胸腺嘧啶

重构是关于其他事情的,新设计中仍然可能会稍微修改代码并重新引入错误,这正是测试所关注的。我想测试的替代方法是在代码中写上“不要操这个”的注释,但这听起来像是做错了:p
Zonko 2012年

1
如果对于单元测试而言过于复杂,则使其成为集成测试的一部分
棘手的怪胎2012年

听起来像这样需要集成测试而不是单元测试。基于您嘲笑太多的事实。我见过的一个一般规则是,您不测试与代码库外部组件通信的代码(与数据库通信,从文件系统读取等等),听起来这也正在做。
卢卡斯

Answers:


27

是的,通常您应该。与所有准则一样,当它们与其他准则背道而驰时,您需要做出最好的判断。对于这种情况,需要权衡错误的严重性与实现测试所需的工作以及针对业务问题并捕获错误状态的回归的测试质量。

我倾向于写测试而不是不写测试,因为中断运行的bug往往比简单地开发和维护单元测试有更多的开销。


我将对此进行更多强调,并指出,在理想情况下,只有存在失败的单元测试时,才将其视为错误,但是斜体+1,并指出应该满足业务需求。
2012年

2
好吧,的确,最终,维护测试所需的时间与新手发现并纠正该错误的时间有关。
Zonko

我也将有利于推广测试,这样它不只是测试中止,当它到达一个特定状态重试工作,而是测试中止并重新尝试在每一个状态下的工作可能会英寸
老临

+1表示“因为中断以消除bug,往往比仅仅开发和维护单元测试要多得多的开销”。
彼得·K。2012年

16

我认为最好的做法是创建一个系统或集成测试,以证明生产中发现的问题,然后进行研究以找到造成该问题的部门,这是我很尴尬的承认我不经常遵循的做法。然后为那些在单元层次上证明问题的单元编写单元测试。进行单元测试后,修复单元,然后运行所有测试。在这一点上,最好不要使用原始测试,因为它可能很脆弱和/或速度很慢,但是为了进行回归和覆盖,请将单元测试保留在自动化套件中。


7

编写测试以识别缺陷的做法是一个好主意,因为它使您能够准确确定需要哪些步骤来重现缺陷并验证是否已修复。此外,这些测试可以作为烟雾测试或回归测试的一部分运行,以确保以后的更改不会将旧的缺陷重新引入系统中。

首先要考虑的是所需的测试级别。验证该修复程序的测试也许更适合于系统级别,或者甚至是手动完成的验收测试。我认为,有一个记录并管理着测试的更为重要,无论它是如何具体实施的。

至于重构如何影响测试,它取决于特定的特性。在某些情况下,重构(或任何类型的工作,例如新功能)可能使测试不再必要。该问题最初发生时可能不再可能。在这种情况下,明智的做法是从可能的测试中删除测试,以使测试过程(自动或手动)更加精简。在其他情况下,有多种方法可以执行测试,并在不同级别验证功能可能更合适。如果该功能较小,则可能根本不需要测试。

您还可以考虑不仅依赖测试,还考虑日志记录。例如,在运行时捕获信息(详细程度取决于环境-在测试过程中更详细,在部署过程中更详细),对应用程序进行性能分析,捕获系统当前状态的转储。如果可以找到问题的常见诱因,则可以使用它来指导各个级别的测试。


5

是的你应该。

为现有代码库编写单元测试。修复错误时,您需要确保单元测试失败-这将使您确信自己确实在处理错误。然后,您需要通过修复错误来重构和使测试通过。

但是,这不是TDD做法。在TDD中,测试会驱动您的设计,但对于您而言,已经确定了设计。

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.