Условно игнорирование тестов в 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(), но не проходит тест.