我应该对已知缺陷进行单元测试吗?


37

如果我的代码包含一个应该修复的已知缺陷,但尚未修复,并且不会在当前版本中修复,并且在可预见的将来可能不会修复,如果该缺陷中的某个单元测试失败,测试套件?如果添加单元测试,它将(显然)会失败,并且习惯于失败的测试似乎是个坏主意。另一方面,如果它是一个已知的缺陷,并且存在一个已知的失败案例,那么将其排除在测试套件之外似乎很奇怪,因为应该在某个时间点对其进行修复,并且该测试已经可以使用。


6
我不这么想,我特别询问单元测试
Martijn 2014年

3
已知缺陷的测试称为回归测试,与单元测试无关……确切地说,后者取决于开发人员的意见-您的问题毕竟可能不是重复的,而是民意测验。尤其值得注意的是,您接受答案根本没有使用“单元测试”一词,而是相当合理地称这些不同的“已知失败测试”
gnat 2014年

3
感谢Michael,这确实对如何在JUnit中标记此类测试有所帮助,但对测试实践却没有帮助。gna,我仍然不明白您如何将失败的单元测试视为回归测试。从您的评论中我也得到了一种特别敌对的被动/攻击性氛围。如果您认为我应该提出不同的问题,请这样说,因为如果您这样说,我将无法解决您的问题。
马丁2014年

3
@gnat:说实话,恕我直言,我们在这里将测试称为“单元”测试还是“回归”测试都没关系-您链接的问题也有不同的重点,那里的答案不适用于此处。
Doc Brown

Answers:


51

答案是肯定的,您应该编写它们并运行它们。

您的测试框架需要“已知失败的测试”类别,您应该将这些测试标记为属于该类别。您如何执行此操作取决于框架。

奇怪的是,突然通过的失败测试与意外失败的通过测试一样有趣。


7
Python单元测试框架中上述功能的示例:docs.python.org/3.3/library/…–
Jace Browning

5

我认为您应该针对当前行为进行单元测试,并在注释中添加正确的测试和正确的行为。例:

@Test
public void test() {
  // this is wrong, it should be fixed some time
  Assert.assertEquals(2, new Calculator().plus(2,2));
  // this is the expected behaviour, replace the above test when the fix is available
  // Assert.assertEquals(4, new Calculator().plus(2, 2));
}

这样,当修复程序可用时,构建将失败,并通知您测试失败。当您查看测试时,您将知道您已更改了行为并且必须更新测试。

编辑:正如曼上尉所说,在大型项目中,这不会很快得到解决,但是出于文档的考虑,原始答案总比没有好。

更好的方法是复制当前测试,使克隆断言正确的事情,@Ignore并用一条消息声明它,例如

@Test
public void test() {
  Assert.assertEquals(2, new Calculator().plus(2,2));
}

@Ignore("fix me, Calculator is giving the wrong result, see ticket BUG-12345 and delete #test() when fixed")
@Test
public void fixMe() {
  Assert.assertEquals(4, new Calculator().plus(2, 2));
}

这与您团队中的约定减少了@Ignored个测试的次数。与引入或更改测试以反映错误的方式相同,不同之处在于,如果这对您的团队至关重要,则不会使构建失败,例如OP表示该错误修复将不包含在当前版本中。


1
这是个坏建议。没有人会尝试修复它。如果有编译问题或测试失败,人们只会打开旧的单元测试。
曼队长

@CaptainMan我同意,我已经更新了答案,以提供一种更好的方法,使开发团队可以在不导致构建失败的情况下意识到错误。您的低票对于我3年前发布的原始答案是合理的,我相信当前答案更合适。你会做另一种方式吗?
Silviu Burcea '18

这几乎是我在极少数情况下由于某种原因现在无法修复该错误的方式。我很想听听您如何处理这种情况@CaptainMan
RubberDuck

@RubberDuck这里实际上没有任何理想的情况(除了现在修复错误哈哈)。对我来说,至少在测试结果中看到“ 10个通过,0个失败,1个被跳过”至少表明一些不熟悉它的人感到有些可疑。我更喜欢这种@Ignore方法。在我看来,仅使用注释不是一个好主意,因为我认为人们不会经常打开单元测试来检查它们(除非它们失败了,或者(希望)当他们想知道为什么忽略了某些东西时) )。
曼队长

@RubberDuck这里实际上没有任何理想的情况(除了现在修复错误哈哈)。对我来说,至少在测试结果中看到“ 10个通过,0个失败,1个被跳过”至少表明一些不熟悉它的人感到有些可疑。我更喜欢这种@Ignore方法。在我看来,仅使用注释不是一个好主意,因为我认为人们不会经常打开单元测试来检查它们(除非它们失败了,或者(有希望)当他们想知道为什么某些东西被跳过了) )。
曼队长

3

根据测试工具的不同,您可以使用omitpend功能。

红宝石示例:

gem 'test-unit', '>= 2.1.1'
require 'test/unit'

MYVERSION = '0.9.0' #Version of the class you test 


class Test_omit < Test::Unit::TestCase
  def test_omit
    omit('The following assertion fails - it will be corrected in the next release')
    assert_equal(1,2)
  end

  def test_omit_if
    omit_if(MYVERSION < '1.0.0', "Test skipped for version #{MYVERSION}")
    assert_equal(1,2)
  end

end

omit命令跳过测试,omit_if将其与测试结合-在我的示例中,我测试版本号,并且仅对希望解决错误的版本执行测试。

我的示例的输出是:

Loaded suite test
Started
O
===============================================================================
The following assertion fails - it will be corrected in the next release [test_omit(Test_omit)]
test.rb:10:in `test_omit'
===============================================================================
O
===============================================================================
Test skipped for version 0.9.0 [test_omit_if(Test_omit)]
test.rb:15:in `test_omit_if'
===============================================================================


Finished in 0.0 seconds.

2 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, 2 omissions, 0 notifications
0% passed

所以我的答案是:实施测试。但是不要将测试人员与错误混为一谈,因为它会导致测试失败。


2

如果您很快就发现了该错误,并且您有时间现在编写单元测试,那么我现在就编写它并将其标记为已知失败,这样它就不会使构建本身失败。您的错误跟踪器应进行更新,以反映当前有一个单元测试无法解决此错误,以便最终负责修复该问题的人员不会再次编写该错误。假设错误的代码不需要大量的重构,并且API发生了很大的变化-如果是这种情况,那么您最好不要编写单元测试,除非您对测试的编写方式有了更好的了解。


1

答案是恕我直言。在开始修复该错误之前,您不应该为该错误添加单元测试,然后您将根据该错误报告编写证明该错误的测试以及该测试失败的时间( s)您将去更正实际代码以使测试通过,并且错误将得到解决,然后将其覆盖。

在我的世界中,我们将有一个手动测试用例,即在修复错误之前,QE均将失败。作为开发人员,我们将通过手动失败的TC和错误跟踪器意识到这一点。

不添加失败的UT的原因很简单。UT用于直接反馈和验证我作为开发人员目前正在从事的工作。在CI系统中使用了UT,以确保我没有在该模块的其他代码区域中无意间破坏了某些内容。让UT故意由于已知错误而失败,恕我直言,这会适得其反,而且纯属错误。


0

我想答案确实是,这取决于。务实一些。现在编写它有什么好处?也许这是新鲜的想法?

修复错误时,通过编写暴露该错误的单元测试来证明它的存在是很有意义的。然后,您修复了该错误,单元测试应该通过了。

您现在是否有时间编写失败的单元测试?是否还有更多急需的功能或错误需要编写/修复。

假设您已经具有功能强大的错误跟踪软件并记录了错误,那么实际上现在就无需编写失败的单元测试

如果在没有漏洞修复的情况下发布发布之前引入失败的单元测试,则可能会引起一些困惑。


0

对于测试套件中的已知故障,我通常会感到不安,因为随着时间的推移,列表很容易增长,或者同一测试中不相关的故障很容易被视为“预期”,因此我很不高兴。间歇性故障也是如此-代码中可能隐藏着一些邪恶的东西。我投票支持现在就为代码编写测试,并且应该在修复后以某种方式注释掉或禁用它。

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.