繁体   English   中英

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

[英]What's the difference between failure and error in JUnit?

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

似乎失败是当您的测试用例失败时 - 即您的断言不正确。 错误是在尝试实际运行测试时发生的意外错误 - 异常等。

如果您的测试抛出一个异常,而该异常并未通过 Junit 中的断言框架冒泡,则会被报告为错误。 例如,一个 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 在 Java 8 中进行实用单元测试”:

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

(也有可能在 JUnit 运行您的测试时抛出异常而未捕获。在这种情况下,JUnit 报告测试错误。)

下面的测试解释了Test Error 与 Test failure之间的区别。

我已经评论了引发测试错误和测试失败的行。

    @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 都会显示测试错误,并在您的预期结果值与您的实际值不匹配时显示测试失败

源类: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() 实例断言错误

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

你是对的,失败来自 JUnit 断言方法抛出的 AssertionErrors,或者抛出 AssertionError,或者抛出你在@Test注释中声明的异常,而错误来自其他意外异常。 但它们之间有一个重要的区别:

失败意味着您的测试运行正确,并确定了代码中的缺陷。

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

简而言之,失败意味着您需要重写正在测试的代码。 错误意味着它可能是您需要重写的单元测试。 这可能意味着即使失败在您的代码中,例如NullPointerException ,因为您检测到了一个您甚至没有测试过的缺陷,因此测试它可能是明智的。

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

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

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

有关更多信息,请查看

测试方法投掷 测试结果
java.lang.AssertionError 失败
org.junit.AssumptionViolatedException 跳过
预期的例外 好的
任何其他例外 错误
没有例外 好的
测试方法之外的异常 错误
  • assert 方法只是抛出 AssertionExceptions。
  • @Test 注释中声明了预期的异常。
  • 测试方法之外的代码可以用@Before、@BeforeClass 等注释。
  • IDE 中的计数报告计数测试(测试方法),而不是断言,因为第一个失败的断言会终止测试。
  • 根据经验,如果测试方法异常终止(不是使用 return 语句),则不成功,反之亦然。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM