为什么Java堆栈跟踪只返回finally块中的失败?

时间:2018-03-19 16:57:00

标签: java

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

try { 
   // Test case steps and validations
} finally { 
   // Clean up related to test
}

注意:由于我的测试不期望例外,因此没有catch阻止。

如果try以及finally阻止测试失败,则只有finally的失败才会在控制台上返回,而不是try。这里的简单示例(此处使用TestNG进行断言) -

try {
    Assert.assertEquals(true, false, "Boolean values did not match");
} finally {
    Assert.assertEquals(100, 10, "Integer values did not match");
}

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

这无法确定查看控制台的实际测试失败。

我想了解为什么Java不会在控制台上返回两个故障详细信息,这可以帮助用户在初看时找出故障原因。

3 个答案:

答案 0 :(得分:4)

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

try {
    throw new RuntimeException("Message 1");
} finally {
    throw new RuntimeException("Message 2");
}

此处仅打印Message 2

Exception in thread "main" java.lang.RuntimeException: Message 2

这是因为当finally抛出异常时,try中的任何例外都会被丢弃并被遗忘":

JLS第14.20.2节

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

         
        
    • 如果finally块正常完成,则由于抛出值V,try语句突然完成。

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

    •   
  •   

答案 1 :(得分:1)

因为幕后Assert.assertEquals()使用Assert.fail()引发AssertionError来表示错误。

finally阻止中的异常将替换并丢弃try阻止initHighlightingOnLoad()阻止的异常。

答案 2 :(得分:1)

这是因为从finally抛出的新异常替换了从try块抛出的异常,如Java语言规范部分{{3 }}:

  

如果try块的执行由于值throw的{​​{1}}突然完成,则可以选择:

     

[...]

     

如果V块因为finally突然完成,那么S语句突然完成,原因为try(以及 Sthrow被丢弃并被遗忘)。

由于V块甚至不知道原始异常,因此它无法对此做任何事情。

但是,如果你finally原始异常,可以将其包含为压缩异常(Java 7+),但它有点复杂:

catch