关于java:有条件地忽略JUnit 4中的测试

Conditionally ignoring tests in JUnit 4

好的,所以@Ignore注释适用于标记不应运行测试用例。

但是,有时我想忽略基于运行时信息的测试。一个例子可能是我需要在具有一定数量内核的机器上运行并发测试。如果这个测试是在单处理器机器上运行的,我认为只是通过测试是不正确的(因为它还没有运行),并且当然不适合测试失败并打破构建。

所以我希望能够在运行时忽略测试,因为这似乎是正确的结果(因为测试框架将允许构建通过但记录测试未运行)。我很确定注释不会给我这种灵活性,并且怀疑我需要手动为相关类创建测试套件。但是,文档没有提到任何关于这一点并且通过API查看它也不清楚如何以编程方式完成(即,我如何以编程方式创建Test或类似的实例,该实例等同于< x0>注释?)。

如果有人在过去做过类似的事情,或者对如何做到这一点有一个明确的想法,我会很高兴听到它。


JUnit的方法是在运行时org.junit.Assume执行此操作。

1
2
3
4
5
 @Before
 public void beforeMethod() {
     org.junit.Assume.assumeTrue(someCondition());
     // rest of setup.
 }

您可以在@Before方法或测试本身中执行此操作,但不能在@After方法中执行。如果您在测试中执行此操作,则@Before方法将运行。您也可以在@BeforeClass中执行此操作以防止类初始化。

假设失败导致测试被忽略。

编辑:要与junit-ext中的@RunIf注释进行比较,他们的示例代码如下所示:

1
2
3
4
5
@Test
public void calculateTotalSalary() {
    assumeThat(Database.connect(), is(notNull()));
    //test code below.
}

更不用说通过这种方式捕获和使用Database.connect()方法的连接要容易得多。


你应该结帐Junit-ext项目。它们具有执行条件测试的RunIf注释,例如:

1
2
3
4
5
6
7
8
9
10
11
@Test
@RunIf(DatabaseIsConnected.class)
public void calculateTotalSalary() {
    //your code there
}

class DatabaseIsConnected implements Checker {
   public boolean satisify() {
        return Database.connect() != null;
   }
}

[代码示例取自他们的教程]


在JUnit 4中,另一个选项可能是创建注释以表示测试需要满足您的自定义条件,然后使用您自己的反射扩展默认运行器,根据自定义条件做出决策。它可能看起来像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class CustomRunner extends BlockJUnit4ClassRunner {
    public CTRunner(Class< ? > klass) throws initializationError {
        super(klass);
    }

    @Override
    protected boolean isIgnored(FrameworkMethod child) {
        if(shouldIgnore()) {
            return true;
        }
        return super.isIgnored(child);
    }

    private boolean shouldIgnore(class) {
        /* some custom criteria */
    }
}

快速说明:Assume.assumeTrue(condition)忽略其余步骤但通过测试。
要使测试失败,请在条件语句中使用org.junit.Assert.fail()。与Assume.assumeTrue()相同,但未通过测试。