简体   繁体   English

JUnit ParentRunner是否应该捕获AssertionError?

[英]Should JUnit ParentRunner catch AssertionError?

I have implemented a custom TestRunner based on BlockJUnit4ClassRunner . 我已经实现了一个基于BlockJUnit4ClassRunner的自定义TestRunner。

My assumption was that any failed assertions (indicating product/requirement issues) would be reported to the notifier via addFailedAssumption() while other exceptions would be reported via addFailure() indicating bugs in the unit test itself. 我的假设是,任何失败的断言(表示产品/需求问题)将通过addFailedAssumption()报告给通知者,而其他异常将通过addFailure()报告,表明单元测试本身存在错误。

Looking at the results, addFailedAssumption() was never called. 查看结果,从未调用过addFailedAssumption() In the source code of ParentRunner .runLeaf() , I see ParentRunner .runLeaf()的源代码中,我看到了

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

The exceptions I get are all of type java.lang.AssertionError . 我得到的异常都是java.lang.AssertionError类型。

Should ParentRunner catch AssertionError or is there a misunderstanding on my side? ParentRunner应该捕获AssertionError还是我这边有误会?

Reading more about this topic, this seems to be a language / translation issue on my side because I'm not a native speaker. 阅读有关此主题的更多信息,这似乎是我方面的语言/翻译问题,因为我不是母语人士。

Finding the class Assume helped me getting it right (I hope) and I'll explain it with an example: 找到Assume类可以帮助我正确理解(希望如此),我将通过一个示例进行说明:

Usage of the AssumtionViolatedException AssumtionViolatedException的用法

Tests can eg run in different environments, let's say different operating systems. 测试可以例如在不同的环境中运行,比如说不同的操作系统。 Maybe the product behaves or needs to behave slightly different on different operating systems, eg because it can use an API call on a newer OS which does not exist in an older version of the OS. 该产品在不同操作系统上的行为或需求可能会略有不同,例如,因为它可以在较新版本的OS中使用API​​调用,而较新版本的OS中不存在该API。 This may result in code like 这可能会导致代码如下

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

The isApiPresent() call will return different results depending on the OS, so you write 2 unit tests and add an assumption about the environment: 根据操作系统的不同, isApiPresent()调用将返回不同的结果,因此您编写了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());
}

If the assumption about the operating system is not given, the test still gets executed due to the @Test annotation, but it should actually be ignored. 如果未给出有关操作系统的假设,则由于@Test批注,该测试仍将执行,但实际上应将其忽略。 The assume...() statements take care of that: they throw an AssumptionViolatedException which can be used to ignore the test. assume...()语句可以解决这一问题:它们引发了一个AssumptionViolatedException ,可用于忽略测试。

Eclipse marks a test with a violated assumption (try assumeFalse(true); ) with an ignore icon: Eclipse用一个忽略的图标标记了一个违反假设的测试(尝试assumeFalse(true); ):

在Eclipse中忽略测试

Usage of AssertionError AssertionError的用法

What I wanted to achieve with my custom implementation of a TestRunner is a bit different. 我想要通过TestRunner的自定义实现实现的目标有些不同。 I wanted to find out which unit tests fail due to a requirement issue and which tests fail due to other exceptions which could indicate a bug in the unit test itself, reconstructing the icons in Eclipse. 我想找出哪些单元测试由于需求问题而失败,以及哪些测试由于其他异常而失败,这些异常可能表明该单元测试本身存在错误,并在Eclipse中重构了这些图标。 Eclipse already distinguishes these two kinds of issues: AssertionError s are marked with blue icons while Exception s are marked with red icons. Eclipse已经区分了这两种类型的问题: AssertionError s用蓝色图标标记,而Exception用红色图标标记。

Eclipse中的红色和蓝色单元测试

For me, this means that I have to implement the decision in fireTestFailure() : 对我来说,这意味着我必须在fireTestFailure()实施该决定:

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

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

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

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