JUnit, часть 2: зачем всё менять?



В JUnit сложилась странная ситуация.



JUnit 4 - топовый java фреймворк для тестов, который используется более чем в 100 тысячах проектов.



JUnit 5 вышел спустя 10 лет и обещает много нового. Но нельзя просто взять и перейти на 5 версию:

▪️ Аннотации вообще другие

▪️ Зависимостей стало больше

▪️ Для совместимости с JUnit 4 надо подключать какой-то винтаж.



Обратная совместимость - обычное дело для java приложений. В новой версии всё работает как раньше. Постепенно добавляешь новые фичи.



Почему JUnit не пошёл по этому пути?



Чтобы ответить на вопрос, нужно копнуть в архитектуру и кейсы использования.



JUnit создавался как удобная библиотека для написания тестов. Для разработчика есть API - аннотации @Test, @Before, методы assertEquals и тд. Здесь всё классно.



Дальше эти тесты запускает IDE или система сборки.



И вот им приходится тяжело. В JUnit 4 API для запуска и анализа тестов очень ограниченный, поэтому IDE и сборщики используют рефлекшн и другие обходные пути.



Чем плох такой подход - понятно. Любое изменение внутренней реализации ломает логику внутри IDE/системы сборки.



JUnit 5 учёл эту проблему и содержит три отдельных артефакта:

🔸 Jupiter - апи для разработчиков

🔸 Platform - апи для запуска и анализа тестов. Целевая аудитория - IDE, плагины и системы сборки. Теперь каждый из них может использовать библиотеку, а не писать свой велосипед

🔸 Vintage - для запуска JUnit 4 тестов на новой платформе



Почему у JUnit 4 и 5 разные аннотации?



У JUnit 5 абсолютно другая кодовая база. Для совместимости с 4 версией пришлось бы наворотить много кода. Гораздо практичнее вынести все адаптеры в отдельный компонент.



Тогда

▫️ Старые тесты будут работать

▫️ Чётко видно, где старые тесты, а где новые. А значит есть шанс, что со временем кодовая база с тестами перейдёт на новую версию.



Что здесь особенного?



В целом выглядит как обычный рефакторинг. Продукт развивается, мир меняется, монолит делится на составные части.



Но в этой истории есть две важные детали.



1️⃣ На страничке принципов разработки команды JUnit есть такие строки:



▫️ JUnit has never tried to be a swiss army knife

▫️ Third party developers move more quickly than we do



Отсюда видна ещё одна мотивация: поощрение развития других библиотек и фреймворков.



Другие разработчики тестовых библиотек теперь могут использовать JUnit платформу и автоматически получать поддержку библиотек во всех IDE и системах сборки.



2️⃣ Вторая инициатива команды JUnit - проект Open Test Alliance for the JVM.



В чём суть: есть много тестовых фреймворков и библиотек. Все они работают по-разному - бросают разные исключения, отличается формат и набор данных и тд. IDE и системам сборки приходится учитывать все особенности.



Идея проекта - создать общую спецификацию для тестовых библиотек. Проект поддержали TestNG, Spock, Hamcrest, AssertJ, Eclipse, IntelliJ, Gradle, Maven и Allure.



Неизвестно, закончится ли эта история удачно, но идея классная.



Здорово, когда компания делает не только хороший продукт, но и способствует развитию отрасли в целом😇