TGViewer
Java: fill the gaps Java: fill the gaps @java_fillthegaps · 12.3K subscribers
Post #334 6.4K
JUnit, часть 3: модели кастомизации

Изменение архитектуры - не всё, чем JUnit 5 отличается от предыдущей версии. Второе отличие касается модели кастомизации.

В этом посте поговорим, зачем это нужно в тестовом фреймворке, и про разницу между 4 и 5 версией.

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

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

Для одного класса это несложно - просто добавляем методы с аннотациями @Before и @After.

А как посчитать время для всех классов? Здесь варианта два:

🔸 Вынести общий код в отдельный класс, в каждый класс-тест добавить методы Before и After. Решение рабочее, но придётся копипастить методы в каждый класс.

🔸 Внедрить логику где-то на верхнем уровне и включать/выключать её через настройки или аннотации.

Это и есть кастомизация - предусмотренные библиотекой места "встраивания" новой логики. JUnit 4 и 5 используют для этого разные механизмы. Давайте кратко их обсудим.

JUnit 4 Runner

Переопределяем жизненный цикл теста целиком. Наследуемся от интерфейса Runner или абстрактного класса, в нужных местах добавляем нужные действия. Теперь тесты запускаются не по стандартной схеме, а по той, что прописана в новом классе.

Примеры:
▫️ @RunWith(Parameterized.class) запускает параметризованные тесты
▫️ @RunWith(Suite.class) запускает наборы тестов
▫️ @RunWith(SpringJUnit4ClassRunner.class) добавляет спринговые активности до и после запуска теста
▫️ @RunWith(MockitoJUnitRunner.class) позволяет использовать заглушки

Главный минус - жизненный цикл только один, значит Runner для теста может быть только один. Не получится совместить несколько фич, например, параметризованные тесты с заглушками.

JUnit 4 Rule

Переопределяем интерфейс TestRule и задаём действие до и после выполнения теста. В тестах выглядит как просто поле:

@Rule
public Timeout globalTimeout = Timeout.seconds(10);

В JUnit 4 есть несколько готовых правил:
▪️ TemporaryFolder - создать временную папку для теста
▪️ ExternalResource - открыть и закрыть внешний ресурс(файл, сокет, БД)

Плюсы-минусы:

✅ Можно использовать несколько rule в одном классе
❌ Работает в рамках одного метода и по сути похож на before/after.

JUnit 5 Extension

Жизненный цикл теста разбивается на 10+ фаз. К каждой из них можно присоединиться, если переопределить нужный интерфейс:
▫️BeforeAllCallback - действие перед всеми тестами
▫️ParameterResolver - передача параметров в тест

Реализуем нужные интерфейсы, регистрируем класс и готово. Похожий механизм используется в Spring.

✅ Класс может использовать несколько экстеншенов
✅ Можно вклиниться на любых этапах жизненного цикла
✅ В интерфейсах доступен контекст выполнения и вся информация про тесты, в итоге возможностей гораздо больше

В JUnit 5 полностью убрали поддержку Runner и Rule, всё переписано на Extension API. Кодовые базы стали несовместимы между собой, поэтому и нужна библиотека Vintage с адаптерами.
______

Разбирать чужие кейсы полезно, но не всегда увлекательно. Поэтому вот интересный факт про разработку JUnit.

JUnit - опенсорсный проект, где никто никому не платил за работу.

Но рефакторинг назревал много лет. Однажды ребята решили, что такие грандиозные планы требуют фулл тайм и объявили краудфандинг на JUnit 5.

Сумма требовалась небольшая - 25 тысяч евро, меньше двух миллионов рублей. В итоге собрали в 2 раза больше, и уже через 6 недель был готов первый прототип.

Меня это очень впечатляет, особенно в сравнении со стоимостью и скоростью разработки в энтерпрайзе🙈
More from @java_fillthegaps
  1. Apr 30, 2026Get Your Hands Dirty on Clean Architecture: отзыв на книгу Когда я подняла тему чистой арх…
  2. Apr 27, 2026​Clean Architecture: отзыв на книгу Наконец-то дочитала книгу Clean Architecture Роберта М…
  3. Mar 4, 2026Как переиспользовать контекст в интеграционных тестах Сегодня расскажу базовый минимум для…
  4. Mar 4, 2026Post #660
  5. Mar 4, 2026Тестовый контекст поднимается 2 минуты. У нас 4 класса с интеграционными тестами, их конфи…
  6. Feb 25, 2026Чистая архитектура. Главы 3-5 Продолжаем спидран по Clean Architecture Роберта Мартина. ⭐️…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →