为什么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;
}
}