Перейти к основному содержимому

Условно запускать или игнорировать тесты в JUnit 4

· 4 мин. чтения

1. Обзор

Давайте представим, что у нас есть тест для некоторого кода, который зависит от операционной системы и должен выполняться только в том случае, если наша тестовая машина работает в Linux. Если он работает на любой другой ОС, мы хотим, чтобы тест не провалился, а игнорировался во время выполнения.

Первый подход может заключаться в использовании нескольких операторов if для проверки этого условия с помощью свойств класса System . Это, конечно, работает, но у JUnit есть более чистый и элегантный метод.

В этом коротком руководстве мы рассмотрим, как мы можем условно запускать или игнорировать тесты в JUnit 4, используя класс Assume .

2. Предполагаемый класс

Этот класс предоставляет набор методов для поддержки выполнения условного теста на основе определенных условий . Наш тест будет работать только при соблюдении всех этих условий. Если нет, JUnit просто пропустит его выполнение и пометит его как пройденный в отчете о тестировании . Последнее является основным отличием от класса Assert , в котором невыполнение условия приводит к тому, что тест завершается с ошибкой .

Важно отметить, что поведение, которое мы описали для класса Assume , является эксклюзивным для исполнителя JUnit по умолчанию . С пользовательскими бегунками все может быть по-другому.

Наконец, так же, как и с Assert , мы можем вызывать методы Assume либо в аннотированных методах @Before или @BeforeClass , либо в самом методе @Test .

Давайте теперь пройдемся по наиболее полезным методам класса Assume , показав несколько примеров. Для всех следующих примеров предположим, что getOsName() возвращает Linux.

2.1. Использование предположения, что

Метод acceptThat() проверяет, что состояние — в данном случае getOsName() — удовлетворяет условиям переданного сопоставителя:

@Test
public void whenAssumeThatAndOSIsLinux_thenRunTest() {
assumeThat(getOsName(), is("Linux"));

assertEquals("run", "RUN".toLowerCase());
}

В этом примере мы проверили, соответствует ли getOsName () Linux . Поскольку getOsName() возвращает Linux , тест будет запущен . Обратите внимание, что здесь мы используем метод сопоставителя Hamcrest is(T) в качестве сопоставителя.

2.2. Использование предположения

Точно так же мы можем использовать метод acceptTrue() для указания логического выражения, которое должно быть истинным для запуска теста. Если он оценивается как false , тест будет проигнорирован:

private boolean isExpectedOS(String osName) {
return "Linux".equals(osName);
}

@Test
public void whenAssumeTrueAndOSIsLinux_thenRunTest() {
assumeTrue(isExpectedOS(getOsName()));

assertEquals("run", "RUN".toLowerCase());
}

В этом случае isExpectedOs() возвращает true . Следовательно, условия для запуска теста выполнены, и тест будет запущен .

2.3. Использование предположенияFalse

Наконец, мы можем использовать противоположный метод acceptFalse() , чтобы указать логическое выражение, которое должно быть ложным , чтобы тест запустился. Если он оценивается как true , тест будет проигнорирован:

@Test
public void whenAssumeFalseAndOSIsLinux_thenIgnore() {
assumeFalse(isExpectedOS(getOsName()));

assertEquals("run", "RUN".toLowerCase());
}

В этом случае, поскольку isExpectedOs() также возвращает true, условия запуска теста не выполнены, и тест будет проигнорирован .

2.4. Использование acceptNotNull

Когда мы хотим игнорировать тест, если какое-то выражение равно null, мы можем использовать метод acceptNotNull() :

@Test
public void whenAssumeNotNullAndNotNullOSVersion_thenRun() {
assumeNotNull(getOsName());

assertEquals("run", "RUN".toLowerCase());
}

Поскольку getOsName() возвращает ненулевое значение, условие запуска теста выполнено, и тест будет запущен.

2.5. Использование предположения без исключения

Наконец, мы могли бы проигнорировать тест, если возникло исключение. Для этой цели мы можем использовать acceptNoException() :

@Test
public void whenAssumeNoExceptionAndExceptionThrown_thenIgnore() {
assertEquals("everything ok", "EVERYTHING OK".toLowerCase());
String t=null;
try {
t.charAt(0);
} catch(NullPointerException npe){
assumeNoException(npe);
}
assertEquals("run", "RUN".toLowerCase());
}

В этом примере, поскольку t равно null, генерируется исключение NullPointerException , поэтому условия для выполнения теста не выполнены, и тест будет проигнорирован .

3. Где мы должны разместить вызов acceptXXX ?

Важно отметить, что поведение методов acceptXXX зависит от того, где мы их размещаем в наших тестах .

Давайте немного изменим наш пример с assertEquals, чтобы сначала выполнялся вызов assertEquals() . Кроме того, давайте сделаем так, чтобы assertEquals() не работал:

@Test
public void whenAssumeFalseAndOSIsLinux_thenIgnore() {
assertEquals("run", "RUN");
assumeFalse(isExpectedOS(getOsName()));
}

Когда мы запустим этот пример, у нас будет:

org.junit.ComparisonFailure: 
Expected :run
Actual :RUN

В этом случае наш тест не игнорируется, потому что он не прошел до того, как мы дошли до вызова acceptThat() . То же самое происходит со всеми методами acceptXXX . Итак, нам нужно убедиться, что мы разместили их в правильном месте внутри нашего тестового метода .

4. Вывод

В этом кратком руководстве мы увидели, как мы можем условно решить, следует ли запускать тест, используя класс Assume в JUnit 4. Если мы используем JUnit 5, он также доступен в версии 5.4 или более поздней версии .

Как всегда, исходный код рассмотренных нами примеров можно найти на GitHub .