Условно игнорируем тесты в JUnit 4
Ок, так @Ignore
аннотация хороша для обозначения того, что контрольный пример не должен выполняться.
Однако иногда я хочу игнорировать тест, основанный на информации времени выполнения. Примером может быть, если у меня есть тест параллелизма, который нужно запустить на машине с определенным количеством ядер. Если бы этот тест выполнялся на однопроцессорной машине, я не думаю, что было бы правильно просто пройти тест (так как он не был запущен), и, конечно, было бы неправильно проваливать тест и нарушать сборку.,
Поэтому я хочу иметь возможность игнорировать тесты во время выполнения, так как это выглядит как правильный результат (поскольку среда тестирования позволит выполнить сборку, но записать, что тесты не выполнялись). Я вполне уверен, что аннотация не даст мне такой гибкости, и подозреваю, что мне нужно будет вручную создать набор тестов для рассматриваемого класса. Однако в документации ничего не говорится об этом, и, просматривая API, также неясно, как это будет сделано программно (то есть, как мне программно создать экземпляр Test
или аналогичные, что эквивалентно тому, что создано @Ignore
аннотация?).
Если кто-то делал что-то подобное в прошлом или имел блестящее представление о том, как еще я мог бы пойти по этому поводу, я был бы рад услышать об этом.
4 ответа
JUnit способ сделать это во время выполнения org.junit.Assume
,
@Before
public void beforeMethod() {
org.junit.Assume.assumeTrue(someCondition());
// rest of setup.
}
Вы можете сделать это в @Before
метод или в самом тесте, но не в @After
метод. Если вы делаете это в самом тесте, ваш @Before
метод будет запущен. Вы также можете сделать это в течение @BeforeClass
предотвратить инициализацию класса.
Предположительный сбой приводит к игнорированию теста.
Изменить: сравнить с @RunIf
аннотация из junit-ext, их пример кода будет выглядеть так:
@Test
public void calculateTotalSalary() {
assumeThat(Database.connect(), is(notNull()));
//test code below.
}
Не говоря уже о том, что намного проще захватить и использовать соединение из Database.connect()
метод таким образом.
Вы должны оформить заказ 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 */
}
}
В дополнение к ответу @tkruse и @Yishai:
я делаю так, чтобы условно пропустить методы тестирования, особенно для
Parameterized
tests, если метод тестирования должен выполняться только для некоторых записей тестовых данных.
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 ...
}
}
Быстрая заметка: Assume.assumeTrue(condition)
игнорирует остальные шаги, но проходит тест. Чтобы не пройти тест, используйте org.junit.Assert.fail()
внутри условного заявления. Работает так же, как Assume.assumeTrue()
но не проходит тест.