Вопрос-ответ

Conditionally ignoring tests in JUnit 4

Условное игнорирование тестов в JUnit 4

Хорошо, итак, @Ignore аннотация хороша для обозначения того, что тестовый пример не следует запускать.

Однако иногда мне хочется проигнорировать тест, основанный на информации о времени выполнения. Примером может быть, если у меня есть тест параллелизма, который необходимо запустить на машине с определенным количеством ядер. Если бы этот тест выполнялся на однопроцессорной машине, я не думаю, что было бы правильно просто пройти тест (поскольку он не был запущен), и, конечно, было бы неправильно провалить тест и прервать сборку.

Итак, я хочу иметь возможность игнорировать тесты во время выполнения, поскольку это кажется правильным результатом (поскольку платформа тестирования позволит выполнить сборку, но запишет, что тесты не были запущены). Я совершенно уверен, что аннотация не даст мне такой гибкости, и подозреваю, что мне нужно будет вручную создать набор тестов для рассматриваемого класса. Однако в документации об этом ничего не упоминается, и при просмотре 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 project. У них есть 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

В дополнение к ответу @tkruse и @Yishai:
Я делаю этот способ условно пропускать методы тестирования, особенно для Parameterized тестов, если метод тестирования должен выполняться только для некоторых записей тестовых данных.

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 ...
}
}
java unit-testing junit