JUnit ParentRunner 应该捕获 AssertionError 吗?

Should JUnit ParentRunner catch AssertionError?

我已经实现了一个基于 BlockJUnit4ClassRunner 的自定义 TestRunner。

我的假设是任何失败的断言(表示 product/requirement 问题)将通过 addFailedAssumption() 报告给通知者,而其他异常将通过 addFailure() 报告,表明单元中的错误测试自己。

查看结果,addFailedAssumption() 从未被调用。在ParentRunner.runLeaf()的源代码中,我看到

try {
    statement.evaluate();
} catch (AssumptionViolatedException e) {
    eachNotifier.addFailedAssumption(e);
} catch (Throwable e) {
    eachNotifier.addFailure(e);
} finally {
    eachNotifier.fireTestFinished();
}

我得到的异常都是java.lang.AssertionError.

类型

应该ParentRunner赶上AssertionError还是我这边有误会?

阅读有关此主题的更多信息,这似乎是我这边的语言/翻译问题,因为我不是母语人士。

找到 class Assume 帮助我做对了(我希望),我将用一个例子来解释它:

AssumtionViolatedException 的用法

测试可以例如运行在不同的环境下,比方说不同的操作系统。也许产品的行为或需要在不同的操作系统上表现略有不同,例如因为它可以在较新的 OS 上使用 API 调用,而旧版本的 OS 中不存在。这可能会导致类似

的代码
if(isApiPresent())
    SimpleAPICall();
else
    // Do some crazy stuff here, potentially slower than the API call

isApiPresent() 调用将 return 不同的结果取决于 OS,因此您编写 2 个单元测试并添加一个关于环境的假设:

@Test
public void isApiPresent_returns_true_on_Win8()
{
    assumeTrue(System.getProperty("os.version").equals("6.2"));
    assertTrue(isApiPresent());
}
@Test
public void isApiPresent_returns_false_on_Win7()
{
    assumeTrue(System.getProperty("os.version").equals("6.1"));
    assertFalse(isApiPresent());
}

如果没有给出关于操作系统的假设,由于 @Test 注释,测试仍然会执行,但实际上应该忽略它。 assume...() 语句负责:它们抛出一个 AssumptionViolatedException 可用于忽略测试。

Eclipse 用忽略图标标记一个违反假设的测试(尝试 assumeFalse(true);):

断言错误的用法

我想通过 TestRunner 的自定义实现实现的目标有点不同。我想找出哪些单元测试由于需求问题而失败,哪些测试由于其他异常而失败,这些异常可能表明单元测试本身存在错误,从而在 Eclipse 中重建图标。 Eclipse 已经区分了这两种问题:AssertionError 标有蓝色图标,而 Exception 标有红色图标。

对我来说,这意味着我必须执行 fireTestFailure() 中的决定:

public void fireTestFailure(Failure failure) {
    originalNotifier.fireTestFailure(failure);

    if (failure.getException().getClass() == AssertionError.class) {
        // Requirement issue
    } else {
        // Unit test issue
    }
}