所以@Ignore注释很好地标记了一个测试用例不应该运行。

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

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 (i.e. how do I programatically create an instance of Test or similar that is equivalent to that created by the @Ignore annotation?).

如果有人在过去做过类似的事情,或者有一个关于我如何做这件事的好主意,我很乐意听听。


当前回答

您应该签出Junit-ext项目。它们有RunIf注释,执行条件测试,例如:

@Test
@RunIf(DatabaseIsConnected.class)
public void calculateTotalSalary() {
    //your code there
}

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

[摘自教程的代码示例]

其他回答

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

快速注意:Assume.assumeTrue(condition)忽略其余步骤,但通过了测试。 要使测试失败,请在条件语句中使用org.junit.Assert.fail()。类似于Assume.assumeTrue(),但测试失败。

JUnit的方法是在运行时使用org. JUnit。

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

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

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

编辑:为了与junit-ext中的@RunIf注释进行比较,它们的示例代码看起来像这样:

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

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

另外@tkruse和@Yishai的回答: 我这样做是为了有条件地跳过测试方法,特别是对于参数化测试,如果一个测试方法应该只对某些测试数据记录运行。

public class MyTest {
    // get current test method
    @Rule public TestName testName = new TestName();
    
    @Before
    public void setUp() {
        org.junit.Assume.assumeTrue(new Function<String, Boolean>() {
          @Override
          public Boolean apply(String testMethod) {
            if (testMethod.startsWith("testMyMethod")) {
              return <some condition>;
            }
            return true;
          }
        }.apply(testName.getMethodName()));
        
        ... continue setup ...
    }
}

您应该签出Junit-ext项目。它们有RunIf注释,执行条件测试,例如:

@Test
@RunIf(DatabaseIsConnected.class)
public void calculateTotalSalary() {
    //your code there
}

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

[摘自教程的代码示例]