Java 有条件地忽略 JUnit 4 中的测试

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1689242/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 21:36:43  来源:igfitidea点击:

Conditionally ignoring tests in JUnit 4

javaunit-testingjunitignore

提问by Andrzej Doyle

OK, so the @Ignoreannotation 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 APIit's also not clear how this would be done programmatically (i.e. how do I programatically create an instance of Testor similar that is equivalent to that created by the @Ignoreannotation?).

所以我希望能够在运行时忽略测试,因为这似乎是正确的结果(因为测试框架将允许构建通过但记录未运行测试)。我相当确定注释不会给我这种灵活性,并怀疑我需要为相关类手动创建测试套件。但是,文档没有提到任何关于此的内容,并且通过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.

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

采纳答案by Yishai

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 @Beforemethod or in the test itself, but not in an @Aftermethod. If you do it in the test itself, your @Beforemethod will get run. You can also do it within @BeforeClassto prevent class initialization.

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

An assumption failure causes the test to be ignored.

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

Edit:To compare with the @RunIfannotation 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()这种方式从方法中捕获和使用连接要容易得多。

回答by notnoop

You should checkout Junit-extproject. They have RunIfannotation that performs conditional tests, like:

你应该结帐Junit-ext项目。它们具有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]

[从他们的教程中获取的代码示例]

回答by TIn TIn

A quick note: Assume.assumeTrue(condition)ignores rest of the steps but passes the test. To fail the test, use org.junit.Assert.fail()inside the conditional statement. Works same like Assume.assumeTrue()but fails the test.

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

回答by Kyle Shrader

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. It may look something like this:

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

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 */
    }
}