«1. Обзор

В этом руководстве мы рассмотрим выполнение условного теста с аннотациями в JUnit 5.

Эти аннотации взяты из пакета условий библиотеки JUnit Jupiter и позволяют нам указывать различные типы условия, при которых наши тесты должны или не должны запускаться.

2. Условия операционной системы

Иногда нам нужно изменить наши тестовые сценарии в зависимости от операционных систем (ОС), на которых они работают. В этих случаях пригодится аннотация @EnabledOnOs.

Использовать @EnabledOnOs просто — нам просто нужно присвоить ему значение для типа ОС. Кроме того, он также принимает аргумент массива, когда мы хотим настроить таргетинг на несколько операционных систем.

Например, предположим, что мы хотим запустить тест только в Windows и macOS:

@Test
@EnabledOnOs({OS.WINDOWS, OS.MAC})
public void shouldRunBothWindowsAndMac() {
    //...
}

Теперь, в отличие от @EnabledOnOs, есть @DisabledOnOs. Как следует из названия, он отключает тесты в соответствии с аргументом типа ОС:

@Test
@DisabledOnOs(OS.LINUX)
public void shouldNotRunAtLinux() {
    //...
}

3. Условия среды выполнения Java

Мы также можем настроить наши тесты для запуска на определенных версиях JRE, используя аннотации @EnableOnJre и @DisableOnJre . Эти аннотации также принимают массив для включения или отключения нескольких версий Java:

@Test
@EnabledOnJre({JRE.JAVA_10, JRE.JAVA_11})
public void shouldOnlyRunOnJava10And11() {
    //...
}

Начиная с JUnit 5.6, мы можем использовать @EnabledForJreRange, чтобы включить тест для определенного диапазона версий Java:

@Test
@EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_13)
public void shouldOnlyRunOnJava8UntilJava13() {
    // this test will only run on Java 8, 9, 10, 11, 12, and 13.
}

По умолчанию минимальное значение — JAVA_8, а максимальное значение — максимально возможная версия JRE. Существует также @DisabledForJreRange для отключения теста для определенного диапазона версий Java:

@Test
@DisabledForJreRange(min = JRE.JAVA_14, max = JRE.JAVA_15)
public void shouldNotBeRunOnJava14AndJava15() {
    // this won't run on Java 14 and 15.
}

Кроме того, если мы хотим отключить наши тесты, работающие с версиями Java, отличными от 8, 9, 10 и 11, мы можем используйте свойство перечисления JRE.OTHER:

@Test
@DisabledOnJre(JRE.OTHER)
public void thisTestOnlyRunsWithUpToDateJREs() {
    // this test will only run on Java 8, 9, 10, and 11.
}

4. Условия свойств системы

Теперь, если мы хотим включить наши тесты на основе свойств системы JVM, мы можем использовать аннотацию @EnabledIfSystemProperty.

Чтобы использовать его, мы должны предоставить именованные и соответствующие аргументы. Именованный аргумент используется для указания точного системного свойства. Совпадения используются для определения шаблона значения свойства с регулярным выражением.

Например, предположим, что мы хотим, чтобы тест выполнялся только тогда, когда имя поставщика виртуальной машины начинается с «Oracle»:

@Test
@EnabledIfSystemProperty(named = "java.vm.vendor", matches = "Oracle.*")
public void onlyIfVendorNameStartsWithOracle() {
    //...
}

Аналогично, у нас есть свойство @DisabledIfSystemProperty для отключения тестов, основанных на системе JVM. характеристики. Чтобы продемонстрировать эту аннотацию, давайте рассмотрим пример:

@Test
@DisabledIfSystemProperty(named = "file.separator", matches = "[/]")
public void disabledIfFileSeperatorIsSlash() {
    //...
}

5. Условия переменных среды

Мы также можем указать условия переменных среды для наших тестов с помощью аннотаций @EnabledIfEnvironmentVariable и @DisabledIfEnvironmentVariable.

И, как и аннотации для условий системных свойств, эти аннотации принимают два аргумента — named и Matches — для указания имени переменной среды и регулярного выражения для сопоставления со значениями переменных среды:

@Test
@EnabledIfEnvironmentVariable(named = "GDMSESSION", matches = "ubuntu")
public void onlyRunOnUbuntuServer() {
    //...
}

@Test
@DisabledIfEnvironmentVariable(named = "LC_TIME", matches = ".*UTF-8.")
public void shouldNotRunWhenTimeIsNotUTF8() {
    //...
}

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

6. Условия на основе сценариев

6.1. Уведомление об устаревании

API условий на основе скриптов и их реализации устарели в JUnit 5.5 и удалены из JUnit 5.6. Для достижения того же результата настоятельно рекомендуется использовать комбинацию встроенных условий или создать пользовательскую реализацию ExecutionCondition.

6.2. Условия

До JUnit 5.6 мы могли указать условия выполнения нашего теста, написав сценарии в аннотациях @EnabledIf и @DisabledIf.

Эти аннотации принимают три аргумента:

    значение — содержит фактический сценарий для запуска. engine (необязательно) — указывает используемый скриптовый движок; по умолчанию используется Oracle Nashorn. причина (необязательно) — для целей ведения журнала указывает сообщение, которое JUnit должен напечатать, если наш тест не пройден.

Итак, давайте рассмотрим простой пример, где мы указываем только однострочный скрипт, без дополнительных аргументов в аннотации:

@Test
@EnabledIf("'FR' == systemProperty.get('user.country')")
public void onlyFrenchPeopleWillRunThisMethod() {
    //...
}

Кроме того, использование @DisabledIf точно такое же:

@Test
@DisabledIf("java.lang.System.getProperty('os.name').toLowerCase().contains('mac')")
public void shouldNotRunOnMacOS() {
    //...
}

~~ ~ Кроме того, мы можем писать многострочные скрипты с аргументом value.

«Давайте напишем краткий пример, чтобы проверить название месяца перед запуском теста.

Мы определим предложение по причине с поддерживаемыми заполнителями:

    {аннотация} – строка для представления экземпляра аннотации. {script} – текст скрипта, который оценивается внутри аргумента value. {result} — строка для представления возвращаемого значения оцениваемого скрипта.

Для этого экземпляра у нас будет многострочный скрипт в качестве аргумента значения и значения для механизма и причины:

@Test
@EnabledIf(value = {
    "load('nashorn:mozilla_compat.js')",
    "importPackage(java.time)",
    "",
    "var thisMonth = LocalDate.now().getMonth().name()",
    "var february = Month.FEBRUARY.name()",
    "thisMonth.equals(february)"
},
    engine = "nashorn",
    reason = "On {annotation}, with script: {script}, result is: {result}")
public void onlyRunsInFebruary() {
    //...
}

Мы можем использовать несколько привязок скрипта при написании наших скриптов:

    systemEnvironment – для доступа к системным переменным среды. systemProperty — для доступа к переменным системных свойств. junitConfigurationParameter — для доступа к параметрам конфигурации. junitDisplayName — отображаемое имя теста или контейнера. junitTags — для доступа к тегам в тестах или контейнере. otherUniqueId — чтобы получить уникальный идентификатор теста или контейнера.

Наконец, давайте посмотрим на другой пример, чтобы увидеть, как использовать скрипты с привязками:

@Test
@DisabledIf("systemEnvironment.get('XPC_SERVICE_NAME') != null" +
        "&& systemEnvironment.get('XPC_SERVICE_NAME').contains('intellij')")
public void notValidForIntelliJ() {
    //this method will not run on intelliJ
}

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

7. Создание пользовательских условных аннотаций

Очень мощной функцией JUnit 5 является возможность создавать пользовательские аннотации. Мы можем определить пользовательские условные аннотации, используя комбинацию существующих условных аннотаций.

Например, предположим, что мы хотим определить, чтобы все наши тесты выполнялись для определенных типов ОС с определенными версиями JRE. Мы можем написать для этого пользовательскую аннотацию:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Test
@DisabledOnOs({OS.WINDOWS, OS.SOLARIS, OS.OTHER})
@EnabledOnJre({JRE.JAVA_9, JRE.JAVA_10, JRE.JAVA_11})
@interface ThisTestWillOnlyRunAtLinuxAndMacWithJava9Or10Or11 {
}

@ThisTestWillOnlyRunAtLinuxAndMacWithJava9Or10Or11
public void someSuperTestMethodHere() {
    // this method will run with Java9, 10, 11 and Linux or macOS.
}

Кроме того, мы можем использовать аннотации на основе сценариев для создания пользовательской аннотации:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@DisabledIf("Math.random() >= 0.5")
@interface CoinToss {
}

@RepeatedTest(2)
@CoinToss
public void gamble() {
    // this method run run roughly 50% of the time
}

8. Заключение

В этой статье мы узнали об условном тестовое выполнение с аннотациями в JUnit 5. Также мы рассмотрели несколько примеров их использования.

Далее мы увидели, как создавать собственные условные аннотации.

Чтобы узнать больше об этой теме, мы можем обратиться к документации JUnit об условном выполнении тестов с аннотациями.

Как обычно, весь пример кода для этой статьи можно найти на GitHub.