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
.
Эти аннотации принимают три аргумента:
value
— содержит фактический скрипт для запуска.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 .
Давайте напишем краткий пример, чтобы проверить название месяца перед запуском теста.
Мы определим предложение по причине
с поддерживаемыми заполнителями:
{annotation}
– строка для представления экземпляра аннотации.{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 .