你如何应对失败的单元测试?

时间:2008-12-22 07:33:25

标签: unit-testing nunit failing-tests

我在解决方案文件中有许多项目,这些项目都为它们编写了单元测试,我希望将它们设置为由我们的持续集成服务器运行。但是,由于许多测试编写得不好而且没有定期运行,因此有很多测试都失败了。

我目前没有时间修复所有测试,但我相信现有测试运行是有价值的。处理失败的单元测试的最佳方法是什么?

我目前正在做的是将每个失败的测试标记为显式并留下TODO评论。

[Test, Explicit] //TODO: Rewrite this test because it fails

有更好的方法吗?或者我应该在将它们包含在由CIS运行的测试之前修复所有测试吗?

6 个答案:

答案 0 :(得分:8)

由于你有一个正在运行的自动构建(带有测试失败通知!),这听起来像是每天5天的时间(从ubuntu社区免费):

在每个失败的测试方法中插入以下(伪代码):

if  ( DateTime.now < new DateTime(2008, 12, 24, 11, 00, 00)) return;

每插入此声明5次,您需要提前一个工作日。在您可能有时间修复测试的某个时间设置时间。

当工作日到来时,您可以修复或删除它。

答案 1 :(得分:6)

好吧,在NUnit中,您可以选择使用ignore属性忽略测试:

[Test, Ignore("Test needs rewrite")]

就个人而言,我对这些测试做了两件事:

  • 如果我不理解测试,或测试是否过时/与当前规格不同步,请删除它们
  • 如果修复很简单,则将其重构为正确的规范

从你所写的内容中收集我会怀疑许多未通过测试的 已经过时了,并且可能首先不相关,所以我认为删除它们会很好

没有必要保持一个没人理解的测试。

更新Oren Eini有一篇博文,其中概述了我对激活旧的失败测试的大部分看法:

The tests has no value by themselves: My most successful project didn't have any tests

引用:

  

测试是一种工具,它的用法应该是   根据通常的指标进行评估   在将其应用于项目之前。那里   有很多理由不使用测试,但是   他们中的大多数归结为:“他们补充道   对过程的摩擦“。

如果改造旧的,失败的测试会给过程带来摩擦,可能根本不值得更新它们。

答案 2 :(得分:3)

我不同意删除测试的想法。如果它看起来应该有效,但事实并非如此,这是重要的信息。如果测试基本上没问题,但是有一些环境导致它失败(例如,读取现在位于不同位置的本地文件),那么当您有时间修复它时,它可以轻松地再次提供价值。但是:

  • 添加注释,解释测试失败的原因如果这是由于其他地方的错误,则错误ID等很有用。确保您提供足够的信息,以便在一年内回复它。
  • 有一些工具(它可能非常简单 - grep!)每周生成一份报告,所以你不要忘记测试。
  • 如果可能的话,找一些定期自动运行被忽略的测试的方法,只是为了检查它们是否仍然失败。失败并且神奇地开始工作的测试可以提供非常重要的信息(当然,与源历史一起)。

答案 3 :(得分:2)

  

我现在没有时间去   修复所有测试

我觉得你有一些落后的东西......

如果你真的认为测试有价值,那么我建议你没有时间来修复它们。现在,他们告诉你软件要么没有做它应该做的事情,要么测试正在检查不再适用的东西。无论哪种方式,都表明该过程在某处被破坏了。

所以,特别考虑到一年中的时间,除非你有月末或年终问题,否则我会花时间清理我的测试或我的代码或两者兼而有之。

说真的,如果你不听他们告诉你的事情,那么进行测试有什么意义呢?如果你不相信它的作用,为什么还要继续进行持续集成?

答案 4 :(得分:1)

您在设置运行所有测试的持续集成服务器方面做得很好。

但是什么是禁用测试有用?它们就像代码注释掉了一样。死测试。作为乔恩 说:让他们运行或删除它们。如果你写的那些写得不好,通常最好写新的。

但你什么时候有时间修理它们?测试是唯一的安全网,软件开发人员在进一步研究时也会如此。 您需要花时间,否则您将在以后付费。但是编写新测试可能需要更少的时间......

答案 5 :(得分:0)

对于累积技术债务的其他代码,您会怎么做?

如果进行TDD(首先测试),单元测试会为您做两件事。一个是帮助设计具有低耦合和高内聚力的物体。这些测试不再适合你。第二,允许您重构代码而不改变行为。

听起来你的失败测试现在是机会成本。换句话说,不再为项目增加价值。只是耗费你的金钱和时间。看看你花时间想知道如何处理它们的时间?测试不再有效。

恕我直言,我会删除测试。它们不再覆盖代码,因此如果您重构代码,则测试不会保护行为。这就像你的代码中的注释已经改变,但注释从未更新过。

如果确实删除了测试,则需要将测试所涵盖的代码视为“Legacy”(羽毛的定义)。