Условно игнорирование тестов в JUnit 4
ОК, поэтому аннотация @Ignore
хороша для обозначения того, что тестовый пример не должен выполняться.
Однако иногда я хочу проигнорировать тест, основанный на информации о времени выполнения. Например, если у меня есть тест concurrency, который должен запускаться на машине с определенным количеством ядер. Если этот тест был запущен на однопроцессорной машине, я не думаю, что было бы правильно просто пройти тест (поскольку он не был запущен), и, конечно, было бы неверно проваливать тест и прерывать сборку.
Итак, я хочу иметь возможность игнорировать тесты во время выполнения, поскольку это похоже на правильный результат (так как тестовая структура позволит сборке проходить, но записывать, что тесты не выполнялись). Я довольно уверен, что аннотация не даст мне такой гибкости и заподозрит, что мне нужно будет вручную создать набор тестов для рассматриваемого класса. Однако в документации ничего не говорится об этом и просматривается API, также не понятно, как это будет сделано программно (то есть как я программно создаю экземпляр Test
или аналогичный, который эквивалентен тому, что создано аннотацией @Ignore
?).
Если кто-то сделал что-то подобное в прошлом или имеет яркое представление о том, как еще я могу это сделать, я был бы рад услышать об этом.
Ответы
Ответ 1
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()
таким образом.
Ответ 2
Вы должны проверить проект Junit-ext
. Они имеют аннотацию RunIf
, которая выполняет условные тесты, например:
@Test
@RunIf(DatabaseIsConnected.class)
public void calculateTotalSalary() {
//your code there
}
class DatabaseIsConnected implements Checker {
public boolean satisify() {
return Database.connect() != null;
}
}
[Пример кода, взятый из их учебника]
Ответ 3
В 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 */
}
}
Ответ 4
Быстрое примечание: Assume.assumeTrue(condition)
игнорирует остальные шаги, но проходит тест.
Чтобы сбой теста, используйте org.junit.Assert.fail()
внутри условного оператора. Работает так же, как Assume.assumeTrue()
, но не проходит тест.