JUnit中的失败和错误之间有什么区别?


93

我正在大型代码库上运行JUnit测试,并且我意识到有时我会收到“错误”,而有时我会收到“失败”。有什么不同?

Answers:


116

好的,我刚刚注意到一个模式,认为我已经弄清楚了(如果我错了,请纠正我)。在我看来,失败是指您的测试用例失败时,即您的断言不正确。错误是尝试实际运行测试时发生的意外错误-异常等。


5
尽管如果java.lang.AssertionError抛出任何扩展,它将显示为测试失败而不是测试错误。您应该考虑接受自己的答案,因为它是正确的。
ponzao 2010年

是的,那是完全不同的。从务实的角度来看,“没有区别”-如果遇到错误或失败,则需要对其进行修复。因此,在JUnit中分别计算“失败”和“错误”可能是一个错误。JUnit 4将两者结合在一起(如下面的答案中所述)。
杰夫·格里格 Jeff Grigg),

如果异常是预期的,你应该注释的@Test使用expected = SomeException.class
Downhillski

@JeffGrigg有一个务实的区别。如果在多个测试用例中都依赖一种行为,那么我仍然只能编写一个断言该行为的测试用例,同时在所有其余情况中抛出未捕获的,可能的运行时异常。这就是说,其余测试用例正在测试其他内容,即使它们仍然依赖于特定行为才能运行。当该行为被破坏时,只有一个测试用例将报告失败,而其余的则报告错误,由此可见,即使许多测试用例没有通过,我也只修复了一个错误。
RonJRH

org.junit.Assert.assertEquals()(如果失败)被JUnit4 HTML报告视为ERROR。这与您的陈述相抵触(我到现在为止都知道)。您能对此多加说明吗?
克里希诺'19

15

如果您的测试引发了一个异常,而该异常没有通过Junit中的Assertion框架冒泡,则将其报告为错误。例如,NullPointer或ClassNotFound异常将报告错误:

String s = null;
s.trim();

要么,

try {

    // your code
} catch(Exception e) {
    // log the exception
    throw new MyException(e);
}

话虽如此,以下内容将报告失败:

Assert.fail("Failure here");

要么,

Assert.assertEquals(1, 2);

甚至:

throw new AssertionException(e);

这取决于您使用的Junit版本。Junit 4-将区分故障和错误,但是Junit 4将其简化为仅故障。

以下链接提供了更多有趣的输入:

http://www.devx.com/Java/Article/31983/1763/page/2


这是不准确的。在JUnit 4中并没有区分测试失败和测试错误。链接的文章具有误导性。它说:“ JUnit 4仅通过使用失败就使它变得更简单”,但是应该强调的是,JUnit 4将java.lang.AssertionError转换为测试失败,因此您不必使用junit.framework.AssertionFailedError。好处是您可以开始在生产代码中编写测试断言,而无需将项目链接到JUnit。在测试错误和测试失败之间进行区分也是非常有用的,如果将其删除,则将倒退一步。
RonJRH

RonJRH,您能够在默认的junit报告中看到错误吗?
尼尔

是的Neel。我刚试过 不确定链接图片的礼节,但这显示了我的测试结果:imagebucket.net/abpxucddkvn1/Capture.PNG
RonJRH,

6

来自“使用JUnit的Java 8中的实用单元测试”:

JUnit中的断言(或断言)是您放入测试的静态方法调用。每个断言都是验证某些条件成立的机会。如果断言的条件不成立,则测试将在此处停止,并且JUnit报告测试失败。

(也有可能,当JUnit运行您的测试时,会引发而不捕获异常。在这种情况下,JUnit报告一个测试错误。)


5

下面的测试解释了测试错误与测试失败之间的区别。

我评论了抛出测试错误和测试失败的行。

    @Test
    public void testErrorVsTestFailure() {

        final String sampleString = null;

        assertEquals('j', sampleString.charAt(0) );
        //above line throws test error as you are trying to access charAt() method on null reference

        assertEquals(sampleString, "jacob");
        //above line throws Test failure as the actual value-a null , is not equal to expected value-string "jacob"
        }

因此,每当您遇到异常时,Junit就会显示测试错误,而当您的预期结果值与实际值不匹配时,它将显示测试失败。


2

源类:JUnitReportReporter.java

public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String defaultOutputDirectory) {
//......

            for (ITestResult tr : (Set) entry.getValue()) {
                TestTag testTag = new TestTag();

                boolean isSuccess = tr.getStatus() == 1;
                if (!(isSuccess)) {
                    if (tr.getThrowable() instanceof AssertionError)
                        ++errors;
                    else {
                        ++failures;
                    }
                }
}

如您在上述方法中看到的以下行

tr.getThrowable()instanceof AssertionError

当它是AssertionError的实例时,错误计数增加,否则(任何Throwable)都计为失败。


1

没错,失败是由JUnit断言方法引发的AssertionErrors引发的,或者是引发AssertionError引发的,还是引发了您在 @Test批注中,而错误来自其他意外的Exceptions。但是它们之间有一个重要的区别:

失败表示您的测试正确运行,并标识了代码中的缺陷。

错误可能意味着您的代码中存在错误,但您甚至没有测试过。这也可能意味着该错误在测试本身中。

简而言之,失败意味着您需要重写正在测试的代码。错误意味着您可能需要重写单元测试。即使失败发生在您的代码中(例如),也可能表示此问题NullPointerException,因为您检测到甚至没有测试的缺陷,因此进行测试可能是明智的。


0

具有讽刺意味的是,junit和其他与测试相关的框架(testng,hamcrest)提供了断言操作来验证条件以及条件是否失败则“在 ”抛出java.lang.AssertionError,顺便说一句,扩展了java.lang.Error。

但这与上面的答案当然完全矛盾。因此,为了将特定的测试流程标记为失败,可以抛出AssertionError,但是我不确定相应的手册中是否确实记录了该错误,因为更适合使用专用的fail()API。其他类型的Throwable将被视为错误,而不是失败。


0

基本上,故障是指未实现的断言,错误是由于异常的测试执行引起的。而且我认为每个IDE的通过失败错误测试都有不同颜色的符号图标。

有关更多信息,请检查

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.