Подпишитесь на наш ТЕЛЕГРАМ КАНАЛ ПО АВТОМАТИЗАЦИИ ТЕСТИРОВАНИЯ
Спустя восемь лет ожидания после выпуска JUnit 5 наконец-то появился JUnit 6. Это не просто небольшое обновление, а серьезный шаг вперед.
В этой статье разберемся, что же изменилось и какие апгрейды ждут пользователей.
JUnit 6 теперь требует Java 17 и выше (а для Kotlin — 2.2+)
В JUnit 6 требование к минимальной версии Java повышено с 8 до 17. Это изменение обусловлено двумя ключевыми факторами:
- Эволюцией Java: с момента выхода Java 8 было внедрено множество улучшений.
- Экосистема смещена в сторону Java 17.
Например:
- Spring Framework 6 и Spring Boot 3 перешли на Java 17+.
- AssertJ также обновил минимальные требования до Java 17+.
В проектах, где по-прежнему используются версии Java ниже 17-й версии, JUnit 5 будет поддерживаться еще как минимум один год.
А для разработчиков на Kotlin есть отдельная новость — JUnit 6 требует Kotlin версии 2.2 или выше.
Единая версия для JUnit Platform, Jupiter и Vintage
Фреймворк JUnit состоит из трех основных архитектурных компонентов:
- Platform — предоставляет API движка для запуска тестов;
- Jupiter — содержит API для написания тестов;
- Vintage — реализует движок, позволяющий запускать тесты, написанные на JUnit 3 и 4.
Однако в JUnit 5 только артефакты Jupiter и Vintage имели одну и ту же версию, в то время как версии артефактов Platform отличались.
Например:
junit-jupiter-engine:5.13.3junit-vintage-engine:5.13.3junit-platform-engine:1.13.3
Как видите, версия junit-platform-engine отличается от других.
В JUnit 6 это наконец исправили — теперь версионирование всех компонентов унифицировано. Platform, Jupiter и Vintage будут иметь одинаковую версию.
В результате, после перехода на JUnit 6 можно использовать одну версию:
junit-jupiter-engine:6.0.0junit-vintage-engine:6.0.0junit-platform-engine:6.0.0
Обновления и удаленные API в JUnit 6
JUnit 6 навел порядок в кодовой базе, удаляет устаревшие API, улучшает совместимость с Kotlin и упрощает архитектуру.
Новые функции и улучшения API:
- В Kotlin теперь можно использовать модификатор
suspendв тестовых и lifecycle-методах. - Отображение имен для
@ParameterizedClassи@ParameterizedTestстало единообразным: аргументы теперь выводятся в форматеname = value(например,fruit = appleвместоfruit=apple). - Для согласованности с тестовыми методами, вложенные классы, аннотированные как
@Nested, теперь упорядочиваются детерминированным, но намеренно неочевидным образом.
Устаревшие и удаленные публичные API:
- Константы перечисления
JREдляJAVA_8–JAVA_16помечены как устаревшие, так как они больше не поддерживаются во время выполнения — теперь базовой являетсяJAVA_17. - Аннотации
@EnabledForJreRangeи@DisabledForJreRangeтеперь используютJAVA_17как минимальное значение по умолчанию. - Удален класс
MethodOrderer.Alphanumeric. - Удален метод
ReflectionSupport.loadClass(String). - Удален метод
ReflectionUtils.readFieldValue(…). - Удален метод
ReflectionUtils.getMethod(…). - Удален метод
InvocationInterceptor.interceptDynamicTest(Invocation, ExtensionContext). - Движок JUnit Vintage теперь считается устаревшим и теперь будет выдавать предупреждение уровня INFO, если обнаружит хотя бы один тест JUnit 4.
Удаленные модули и интеграции:
- Модули
junit-platform-runnerиjunit-platform-jfrудалены; функциональность JFR перенесена вjunit-platform-launcher. - Модуль
junit-platform-suite-commonsтеперь интегрирован вjunit-platform-suite. - Артефакт
junit-jupiter-migrationsupportи все его классы помечены как устаревшие и будут удалены в следующем мажорном релизе.
Совместимость с инструментами сборки:
- Поддержка Maven Surefire/Failsafe версий ниже 3.0.0 прекращена.
Полный список изменений доступен в официальных Release Notes.
Более стабильный и быстрый парсинг CSV для @CsvSource и @CsvFileSource
В JUnit 6 реализация CSV-парсинга перенесена из больше не поддерживаемой библиотеки univocity-parsers в FastCSV.
Благодаря этому обеспечены:
- более последовательная обработка входных данных CSV (в том числе для некорректных записей);
- улучшенная диагностика и сообщения об ошибках;
- улучшенная производительность.
Хотя в целом поведение остается совместимым с JUnit 5, есть несколько изменений, на которые стоит обратить внимание — возможно, потребуется обновить тесты или входные CSV-файлы:
- Атрибут
lineSeparatorв@CsvFileSourceбыл удален. Теперь разделитель строк определяется автоматически — поддерживаются все варианты:\r,\nи\r\n. - В
@CsvSourceи@CsvFileSourceтеперь запрещены лишние символы после закрывающей кавычки. Например, если используется одиночная кавычка, то строка'foo’INVALID,'bar'вызовет исключение. Это помогает поймать битые CSV-данные. - Атрибуты вроде
ignoreLeadingAndTrailingWhitespace,nullValuesи другие теперь применяются не только к обычным полям, но и к заголовкам. - Тексты и причины исключений, выбрасываемых при ошибках в CSV, могут отличаться от прежних.
Если ваш проект использует сложные или нестандартные CSV-данные в тестах, рекомендуется проверить корректность данных после перехода на JUnit 6.
JUnit 6 усиливает null-безопасность с помощью аннотаций JSpecify
В JUnit 5 возможность присвоения значения null описывалась неформально с помощью JavaDoc — это было удобно для людей, но невидимо для инструментов. В результате часто возникали проблемы:
- NullPointerException во время выполнения;
- Избыточные проверки на
nullили касты в Kotlin, где типы делятся на nullable и non-nullable.
JUnit 6 решает эти проблемы,добавив поддержку аннотаций JSpecify. Теперь:
- IDE корректно распознают null-аннотации;
- статические анализаторы вроде ErrorProne и NullAway используют их при проверках;
- компилятор Kotlin тоже учитывает эти аннотации.
Начиная с JUnit 6, все публичные API явно указывают null-статус с помощью @Nullable.
Например, метод Arguments.of() теперь четко указывает, что он принимает null-аргументы, но всегда возвращает не-null значение:
static Arguments of(@Nullable Object... arguments) {
return of(arguments);
}
Типы без аннотаций считаются non-null по умолчанию.
Заключение
JUnit 6 — это важный этап в развитии фреймворка. Вместо полного переписывания, как в JUnit 5, разработчики сосредоточились на качестве и удобстве. Среди ключевых изменений:
- использование современных возможностей Java;
- внедрение полноценной null-безопасности с помощью JSpecify;
- упрощение работы с зависимостями.
Перевод статьи «What’s new in JUnit 6: Key Changes and Improvements».