1. Обзор
По умолчанию JUnit запускает тесты в детерминированном, но непредсказуемом порядке ( MethodSorters.DEFAULT
).
В большинстве случаев такое поведение совершенно нормально и приемлемо. Но бывают случаи, когда нам нужно обеспечить соблюдение определенного порядка.
2. Тестовый заказ в JUnit 5
В JUnit 5 мы можем использовать @TestMethodOrder
для управления порядком выполнения тестов.
Мы можем использовать наш собственный MethodOrderer
, как мы увидим позже.
Или мы можем выбрать один из трех встроенных ордеров:
Буквенно-цифровой
порядок@Заказать
аннотацию- Случайный порядок
2.1. Использование буквенно-цифрового
порядка
JUnit 5 поставляется с набором встроенных реализаций MethodOrderer
для запуска тестов в алфавитно-цифровом порядке.
Например, он предоставляет MethodOrderer.MethodName
для сортировки тестовых методов на основе их имен и списков их формальных параметров :
@TestMethodOrder(MethodOrderer.MethodName.class)
public class AlphanumericOrderUnitTest {
private static StringBuilder output = new StringBuilder("");
@Test
void myATest() {
output.append("A");
}
@Test
void myBTest() {
output.append("B");
}
@Test
void myaTest() {
output.append("a");
}
@AfterAll
public static void assertOutput() {
assertEquals("ABa", output.toString());
}
}
Точно так же мы можем использовать MethodOrderer.DisplayName
для сортировки методов в алфавитно-цифровом порядке на основе их отображаемых имен.
Пожалуйста, имейте в виду, что MethodOrderer.Alphanumeric
— это еще одна альтернатива. Однако эта реализация устарела и будет удалена в версии 6.0.
2.2. Использование аннотации @Order
Мы можем использовать аннотацию @Order
, чтобы принудительно запускать тесты в определенном порядке.
В следующем примере методы будут запускать firstTest()
, затем secondTest()
и, наконец , ThirdTest()
:
@TestMethodOrder(OrderAnnotation.class)
public class OrderAnnotationUnitTest {
private static StringBuilder output = new StringBuilder("");
@Test
@Order(1)
void firstTest() {
output.append("a");
}
@Test
@Order(2)
void secondTest() {
output.append("b");
}
@Test
@Order(3)
void thirdTest() {
output.append("c");
}
@AfterAll
public static void assertOutput() {
assertEquals("abc", output.toString());
}
}
2.3. Использование случайного порядка
Мы также можем псевдослучайно упорядочивать методы тестирования, используя реализацию MethodOrderer.Random
:
@TestMethodOrder(MethodOrderer.Random.class)
public class RandomOrderUnitTest {
private static StringBuilder output = new StringBuilder("");
@Test
void myATest() {
output.append("A");
}
@Test
void myBTest() {
output.append("B");
}
@Test
void myCTest() {
output.append("C");
}
@AfterAll
public static void assertOutput() {
assertEquals("ACB", output.toString());
}
}
На самом деле JUnit 5 использует System.nanoTime()
в качестве начального значения по умолчанию для сортировки тестовых методов. Это означает, что порядок выполнения методов может не совпадать в повторяющихся тестах.
Однако мы можем настроить пользовательское начальное число, используя свойство junit.jupiter.execution.order.random.seed
для создания повторяющихся сборок.
Мы можем указать значение нашего пользовательского начального числа в файле junit-platform.properties
:
junit.jupiter.execution.order.random.seed=100
2.4. Использование пользовательского заказа
Наконец, мы можем использовать собственный заказ, реализуя интерфейс MethodOrderer
. ** **
В нашем CustomOrder
мы упорядочим тесты на основе их имен в буквенно-цифровом порядке без учета регистра:
public class CustomOrder implements MethodOrderer {
@Override
public void orderMethods(MethodOrdererContext context) {
context.getMethodDescriptors().sort(
(MethodDescriptor m1, MethodDescriptor m2)->
m1.getMethod().getName().compareToIgnoreCase(m2.getMethod().getName()));
}
}
Затем мы будем использовать CustomOrder
для запуска тех же тестов из нашего предыдущего примера в порядке myATest()
, myaTest()
и, наконец , myBTest()
:
@TestMethodOrder(CustomOrder.class)
public class CustomOrderUnitTest {
// ...
@AfterAll
public static void assertOutput() {
assertEquals("AaB", output.toString());
}
}
2.5. Установить порядок по умолчанию
JUnit 5 предоставляет удобный способ установить порядок методов по умолчанию с помощью параметра junit.jupiter.testmethod.order.default
.
Точно так же мы можем настроить наш параметр в файле junit-platform.properties
:
junit.jupiter.testmethod.order.default = org.junit.jupiter.api.MethodOrderer$DisplayName
Порядок по умолчанию будет применяться ко всем тестам, которые не квалифицированы с помощью @TestMethodOrder
.
Еще одна важная вещь, о которой следует упомянуть, это то, что указанный класс должен реализовывать интерфейс MethodOrderer
.
3. Тестовый заказ в JUnit 4
Для тех, кто все еще использует JUnit 4, API-интерфейсы для заказа тестов немного отличаются.
Давайте рассмотрим варианты достижения этого и в предыдущих версиях.
3.1. Использование MethodSorters.DEFAULT
Эта стратегия по умолчанию сравнивает методы тестирования, используя их хэш-коды.
В случае хеш-коллизии используется лексикографический порядок:
@FixMethodOrder(MethodSorters.DEFAULT)
public class DefaultOrderOfExecutionTest {
private static StringBuilder output = new StringBuilder("");
@Test
public void secondTest() {
output.append("b");
}
@Test
public void thirdTest() {
output.append("c");
}
@Test
public void firstTest() {
output.append("a");
}
@AfterClass
public static void assertOutput() {
assertEquals(output.toString(), "cab");
}
}
Когда мы запустим тесты в классе выше, мы увидим, что все они пройдены, включая assertOutput()
.
3.2. Использование MethodSorters.JVM
Еще одна стратегия упорядочивания — MethodSorters.JVM
.
Эта стратегия использует естественный порядок JVM, который может быть разным для каждого запуска :
@FixMethodOrder(MethodSorters.JVM)
public class JVMOrderOfExecutionTest {
// same as above
}
Каждый раз, когда мы запускаем тесты в этом классе, мы получаем другой результат.
3.3. Использование MethodSorters.NAME_ASCENDING
Наконец, эту стратегию можно использовать для запуска тестов в их лексикографическом порядке:
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class NameAscendingOrderOfExecutionTest {
// same as above
@AfterClass
public static void assertOutput() {
assertEquals(output.toString(), "abc");
}
}
Когда мы запускаем тесты в этом классе, мы видим, что все они проходят, включая assertOutput()
. Это подтверждает порядок выполнения, который мы установили с помощью аннотации.
4. Вывод
В этой быстрой статье мы рассмотрели способы установки порядка выполнения, доступные в JUnit.
Как всегда, примеры, использованные в этой статье, можно найти на GitHub .