【问题标题】:How do you deal with failing Unit Tests?你如何处理失败的单元测试?
【发布时间】:2008-12-22 07:33:25
【问题描述】:

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

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

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

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

有没有更好的方法来做到这一点?还是应该先修复所有测试,然后再将它们包含在 CIS 运行的测试中?

【问题讨论】:

    标签: unit-testing nunit failing-tests


    【解决方案1】:

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

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

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

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

    当工作日到来时,你修复它或删除它。

    【讨论】:

      【解决方案2】:

      嗯,在 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

      引用:

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

      如果改造旧的、失败的测试会增加流程的摩擦,也许根本不值得更新它们。

      【讨论】:

      • 您还可以在 [IgnoreAttribute] 中添加注释,这样它们仍然更有用。
      • 罗杰,感谢您提醒我...编辑了答案以使用忽略评论:)
      • 我投票给这个答案是因为它对我帮助最大。在忽略属性中添加注释确实很有帮助。我也喜欢 krosenvold 和 Jon Skeet 的回答。目前我只会标记测试并在删除或替换它们之前通知上级。
      【解决方案3】:

      我不同意只删除测试的想法。如果它看起来应该可以工作,但它没有,这是重要的信息。如果一个测试基本没问题,但是有一些环境因素导致它失败(例如,读取现在位于不同位置的本地文件),那么当你有时间修复它时,它可以很容易地再次提供价值。然而:

      • 添加注释说明测试失败的原因 如果这是由于其他地方的错误,错误 ID 等很有用。确保您提供了足够的信息,以便在一年后再次访问。
      • 使用一些工具(它可能非常简单 - grep!)每周生成一份报告,这样您就不会忘记测试。
      • 如果可能,请找到某种方法定期自动运行被忽略的测试,以检查它们是否仍然失败。失败并神奇地开始工作的测试可以提供非常重要的信息(当然,结合源历史记录)。

      【讨论】:

        【解决方案4】:

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

        我认为你在这里有一些落后的东西......

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

        因此,特别是考虑到一年中的某个时间,除非您有月末或年终问题,否则我会抽出时间清理我的测试或代码,或两者兼而有之。

        说真的,如果你不听他们告诉你的话,那么进行测试有什么意义呢?如果您不相信持续集成的功能,为什么还要麻烦运行它呢?

        【讨论】:

          【解决方案5】:

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

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

          但是您什么时候有时间修复它们?测试是唯一的安全网,软件开发人员在进一步发展时拥有。 你需要花时间,否则你以后会为它付出代价。但也许编写新测试会花费更少的时间......

          【讨论】:

            【解决方案6】:

            你会如何处理其他一些积累了技术债务的代码?

            如果进行 TDD(先测试),单元测试会为您做两件事。一是帮助设计具有低耦合和高内聚的对象。这些测试不再为你做傻事。第二,允许您在不改变行为的情况下重构代码。

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

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

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

            【讨论】:

              猜你喜欢
              • 2021-01-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-01-22
              • 1970-01-01
              • 2014-05-04
              • 1970-01-01
              相关资源
              最近更新 更多