Ответ
JUnit 5 (Jupiter) — это полная переработка фреймворка, решающая архитектурные ограничения JUnit 4.
Основные отличия:
-
Архитектура:
- JUnit 4: Монолитный JAR.
- JUnit 5: Модульная платформа из трех частей: Jupiter (новый API), Vintage (запуск старых JUnit 4 тестов), Platform (запуск на разных инструментах).
-
Аннотации и API:
@Testбольше не имеет параметровtimeoutиexpected. Вместо них используются утверждения:// JUnit 5 assertTimeout(Duration.ofSeconds(1), () -> ...); assertThrows(NullPointerException.class, () -> ...);@Before/@After→@BeforeEach/@AfterEach.@BeforeClass/@AfterClass→@BeforeAll/@AfterAll(методы теперь могут бытьstaticилиinstanceпри использовании@TestInstance(Lifecycle.PER_CLASS)).
-
Новые возможности:
@DisplayName: Человекочитаемые имена для тестов и классов.@Nested: Логическая группировка тестов во внутренних классах.@TestFactory: Динамическое создание тестовых случаев во время выполнения.@Tag: Гибкая фильтрация тестов для запуска.- Расширения: Мощная замена
@Ruleи@RunWithчерез@ExtendWith.
Пример теста JUnit 5:
@DisplayName("Калькулятор")
class CalculatorTest {
@Nested
@DisplayName("Тесты сложения")
class AddTests {
@Test
@DisplayName("1 + 1 = 2")
void shouldAddTwoNumbers() {
assertEquals(2, Calculator.add(1, 1),
() -> "1 + 1 должно равняться 2"); // Ленивое сообщение
}
}
}
Миграция: JUnit 5 обратно совместим через модуль JUnit Vintage, который позволяет запускать JUnit 4 тесты в среде JUnit 5.
Ответ 18+ 🔞
А, ну это ж про JUnit, блядь! Слушай, история такая: был у нас JUnit 4, старый добрый, но, как водится, весь в архитектурных костылях. И вот приходит JUnit 5, он же Jupiter, и такой: "Ну нахуй, ребята, всё переписываем, но по-умному!"
Чё там поменялось, ёпта:
-
Архитектура, блядь:
- JUnit 4: Один жирный JAR, как монолит, блядь. Всё в кучу.
- JUnit 5: Разобрали на три модуля, как конструктор. Jupiter — это новые плюшки и API, Vintage — чтоб старые тесты JUnit 4 не выкидывать, а Platform — чтоб всякие IDE и сборщики могли с этим хозяйством работать. Умно, сука!
-
Аннотации и API — тут просто пиздец изменений:
- Раньше в
@Testможно былоtimeoutиexpectedвпихнуть. Теперь — хуй! Всё через утверждения, ясень пень:// JUnit 5 assertTimeout(Duration.ofSeconds(1), () -> ...); // Ждём секунду, а потом — пошёл нахуй, тест упал assertThrows(NullPointerException.class, () -> ...); // Ожидаем, что тут вылетит NPE, и радуемся, когда вылетает @Before/@Afterпереименовали в@BeforeEach/@AfterEach. Так понятнее, блядь, что перед КАЖДЫМ тестом.@BeforeClass/@AfterClassстали@BeforeAll/@AfterAll. И внимание, ёпта — методы теперь могут быть не толькоstatic, но и обычными, если сверху класса написать@TestInstance(Lifecycle.PER_CLASS). Гибкость, мать её!
- Раньше в
-
Новые плюшки, от которых глаза на лоб лезут:
@DisplayName: Можно дать тесту человеческое имя, типа "Проверка, что сервис не сдохнет от null". Красота, а неtestServiceWithNullShouldNotThrow, блядь.@Nested: Группируй тесты во внутренних классах, чтоб не было одной сраной кучи методов. Порядок, сука!@TestFactory: Это вообще магия. Динамически тесты генерируй прямо во время выполнения. Хули тебе ещё надо?@Tag: Навешивай на тесты метки и потом запускай только "медленные" или только "интеграционные". Фильтрация — огонь.- Расширения: Вместо старых костылей
@Ruleи@RunWithтеперь есть@ExtendWith. Мощь нереальная.
Вот, смотри, как теперь тесты выглядят, просто песня:
@DisplayName("Калькулятор") // Смотри какая красота, а не просто CalculatorTest
class CalculatorTest {
@Nested
@DisplayName("Тесты сложения") // Группочка!
class AddTests {
@Test
@DisplayName("1 + 1 = 2") // Во, блядь, сразу ясно, что проверяем
void shouldAddTwoNumbers() {
assertEquals(2, Calculator.add(1, 1),
() -> "1 + 1 должно равняться 2"); // Сообщение об ошибке ленивое, вычисляется только если тест упал. Умно, ёпта!
}
}
}
А как мигрировать, если старый код есть? Да не ссы, чувак! JUnit 5 обратно совместим через модуль JUnit Vintage. Он как переводчик для старых тестов JUnit 4 — запускает их в новой среде. Так что можно постепенно переползать, не теряя всё сразу. Удобно, блядь, как швейцарские часы!