Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Java stacktrace只在finally块中返回失败?_Java - Fatal编程技术网

为什么Java stacktrace只在finally块中返回失败?

为什么Java stacktrace只在finally块中返回失败?,java,Java,我已经编写了一些自动化测试,其中我使用了如下语法- try { // Test case steps and validations } finally { // Clean up related to test } 注意:这没有catch块,因为我的测试不需要异常 如果在try和finally块中测试失败,控制台上只返回finally的失败,而不返回try的失败。这里有一个简单的例子(TestNG用于断言)- 在这种情况下,只返回最终失败的详细信息 这无助于识别控制台测试的实

我已经编写了一些自动化测试,其中我使用了如下语法-

try { 
   // Test case steps and validations
} finally { 
   // Clean up related to test
}
注意:这没有
catch
块,因为我的测试不需要异常

如果在
try
finally
块中测试失败,控制台上只返回
finally
的失败,而不返回
try
的失败。这里有一个简单的例子(TestNG用于断言)-

在这种情况下,只返回最终失败的详细信息

这无助于识别控制台测试的实际失败


我想理解为什么Java不在控制台上返回这两个故障详细信息,这可以帮助用户一眼就识别故障原因。

因为在后台
Assert.assertEquals()
使用
Assert.fail()
抛出
AssertionError


finally
块中的异常将替换并丢弃在
try
块中抛出的异常,如下所示。

抛出异常时可以观察到同样的情况:

try {
    throw new RuntimeException("Message 1");
} finally {
    throw new RuntimeException("Message 2");
}
此处仅打印
消息2

Exception in thread "main" java.lang.RuntimeException: Message 2
这是因为当
最后
抛出异常时,
try
中的任何异常都将被“丢弃并遗忘”:

JLS第14.20.2节

  • 如果V的运行时类型与try语句的任何catch子句的可捕获异常类不兼容, 然后执行finally块。还有一个选择:

    • 如果finally块正常完成,那么try语句会因为抛出值V而突然完成

    • 如果finally块因原因S而突然完成,则try语句因原因S(和抛出值)而突然完成 V被丢弃和遗忘


这是因为从
finally
块抛出的新异常替换了从
try
块抛出的异常,如Java语言规范第节所述:

如果由于值
V
throw
而导致
try
块的执行突然完成,则有一个选择:

[……]

如果
finally
块因原因而突然完成
S
,则
try
语句因原因而突然完成
S
(并且
V
抛出将被丢弃和遗忘

由于
finally
块甚至不知道原始异常,因此它无法对其执行任何操作

但是,如果捕获原始异常,可以将其作为抑制异常(Java 7+),但它有点复杂:

AssertionError originalError = null;
try {
    Assert.assertEquals(true, false, "Boolean values did not match");
} catch (AssertionError e) {
    originalError = e;
    throw e;
} finally {
    try {
        Assert.assertEquals(100, 10, "Integer values did not match");
    } catch (AssertionError e) {
        if (originalError == null)
            throw e;
        originalError.addSuppressed(e);
        throw originalError;
    }
}

它没有更高的优先级。如果一个
finally
块在已经处理异常时抛出异常,它将替换该异常,或者按照调用它的方式:原始异常被“丢弃并遗忘”。我将研究您的测试框架设置/拆除测试的能力,而不是在测试中手动设置和拆除(就像您看起来正在做的那样)
AssertionError originalError = null;
try {
    Assert.assertEquals(true, false, "Boolean values did not match");
} catch (AssertionError e) {
    originalError = e;
    throw e;
} finally {
    try {
        Assert.assertEquals(100, 10, "Integer values did not match");
    } catch (AssertionError e) {
        if (originalError == null)
            throw e;
        originalError.addSuppressed(e);
        throw originalError;
    }
}