本文翻译自:Conditionally ignoring tests in JUnit 4
OK, so the @Ignore
annotation is good for marking that a test case shouldn't be run. 好的,所以@Ignore
注释适用于标记不应运行测试用例。
However, sometimes I want to ignore a test based on runtime information. 但是,有时我想忽略基于运行时信息的测试。 An example might be if I have a concurrency test that needs to be run on a machine with a certain number of cores. 一个例子可能是我需要在具有一定数量内核的机器上运行并发测试。 If this test were run on a uniprocessor machine, I don't think it would be correct to just pass the test (since it hasn't been run), and it certainly wouldn't be right to fail the test and break the build. 如果这个测试是在单处理器机器上运行的,我认为只是通过测试是不正确的(因为它还没有运行),并且当然不适合测试失败并打破构建。
So I want to be able to ignore tests at runtime, as this seems like the right outcome (since the test framework will allow the build to pass but record that the tests weren't run). 所以我希望能够在运行时忽略测试,因为这似乎是正确的结果(因为测试框架将允许构建通过但记录测试未运行)。 I'm fairly sure that the annotation won't give me this flexibility, and suspect that I'll need to manually create the test suite for the class in question. 我很确定注释不会给我这种灵活性,并且怀疑我需要手动为相关类创建测试套件。 However, the documentation doesn't mention anything about this and looking through the API it's also not clear how this would be done programmatically (ie how do I programatically create an instance of Test
or similar that is equivalent to that created by the @Ignore
annotation?). 但是,文档没有提到任何关于这一点并且通过API查看它也不清楚如何以编程方式完成(即我如何以编程方式创建Test
的实例或类似于@Ignore
注释创建的实例?)。
If anyone has done something similar in the past, or has a bright idea of how else I could go about this, I'd be happy to hear about it. 如果有人在过去做过类似的事情,或者对如何做到这一点有一个明确的想法,我会很高兴听到它。
#1楼
参考:https://stackoom.com/question/75Rq/有条件地忽略JUnit-中的测试
#2楼
You should checkout Junit-ext
project. 你应该检查Junit-ext
项目。 They have RunIf
annotation that performs conditional tests, like: 它们具有执行条件测试的RunIf
注释,例如:
@Test
@RunIf(DatabaseIsConnected.class)
public void calculateTotalSalary() {
//your code there
}
class DatabaseIsConnected implements Checker {
public boolean satisify() {
return Database.connect() != null;
}
}
[Code sample taken from their tutorial] [代码示例取自他们的教程]
#3楼
The JUnit way is to do this at run-time is org.junit.Assume
. JUnit的方法是在运行时执行此操作是org.junit.Assume
。
@Before
public void beforeMethod() {
org.junit.Assume.assumeTrue(someCondition());
// rest of setup.
}
You can do it in a @Before
method or in the test itself, but not in an @After
method. 您可以在@Before
方法或测试本身中执行此操作,但不能在@After
方法中执行。 If you do it in the test itself, your @Before
method will get run. 如果你在测试中做到这一点,你的@Before
方法就会运行。 You can also do it within @BeforeClass
to prevent class initialization. 您也可以在@BeforeClass
执行此操作以防止类初始化。
An assumption failure causes the test to be ignored. 假设失败导致测试被忽略。
Edit: To compare with the @RunIf
annotation from junit-ext , their sample code would look like this: 编辑:要与junit-ext中的@RunIf
注释进行比较,他们的示例代码如下所示:
@Test
public void calculateTotalSalary() {
assumeThat(Database.connect(), is(notNull()));
//test code below.
}
Not to mention that it is much easier to capture and use the connection from the Database.connect()
method this way. 更不用说以这种方式从Database.connect()
方法捕获和使用连接要容易得多。
#4楼
A quick note: Assume.assumeTrue(condition)
ignores rest of the steps but passes the test. 快速说明: Assume.assumeTrue(condition)
忽略其余步骤但通过测试。 To fail the test, use org.junit.Assert.fail()
inside the conditional statement. 要使测试失败,请在条件语句中使用org.junit.Assert.fail()
。 Works same like Assume.assumeTrue()
but fails the test. 像Assume.assumeTrue()
但测试失败。
#5楼
In JUnit 4, another option for you may be to create an annotation to denote that the test needs to meet your custom criteria, then extend the default runner with your own and using reflection, base your decision on the custom criteria. 在JUnit 4中,另一个选项可能是创建注释以表示测试需要满足您的自定义条件,然后使用您自己的反射扩展默认运行器,根据自定义条件做出决策。 It may look something like this: 它可能看起来像这样:
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 */
}
}