Условно игнорируя тесты в JUnit 4


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

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

поэтому я хочу иметь возможность игнорировать тесты во время выполнения, так как это кажется правильным результатом (поскольку тестовая среда позволит сборке пройти, но записать, что тесты не были запущены). Я почти уверен, что аннотация не даст мне такой гибкости, и подозреваю, что мне нужно будет вручную создать набор тестов для рассматриваемого класса. Однако в документации ничего не говорится об этом и просматривается API это тоже не ясно, как это будет сделано программно (т. е. как я программно создать экземпляр Test или аналогичный, что эквивалентно тому, что создано @Ignore аннотации?).

Если кто-то сделал что-то подобное в прошлом, или имеет яркое представление о том, как еще я мог бы пойти об этом, я был бы рад услышать об этом.

4 289

4 ответа:

JUnit способ сделать это во время выполнения является org.junit.Assume.

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

вы можете сделать это @Before метод или в самом тесте, но не в @After метод. Если вы сделаете это в самом тесте, ваш @Before метод будет работать. Вы также можете сделать это в пределах @BeforeClass для предотвращения инициализации класса.

ошибка предположения приводит к игнорированию теста.

Edit: для сравнения с @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 */
    }
}

небольшое примечание: Assume.assumeTrue(condition) игнорирует остальные шаги, но проходит тест. Чтобы провалить тест, используйте org.junit.Assert.fail() внутри условного оператора. Работает так же, как Assume.assumeTrue() но не проходит тест.