Ответ
Работал с JUnit 5 (Jupiter), актуальной архитектурой для модульного тестирования. Для поддержки legacy-кода знаком и с JUnit 4.
Ключевые отличия JUnit 5 от JUnit 4:
- Архитектура: JUnit 5 состоит из трёх модулей (Jupiter, Vintage, Platform).
- Пакеты: Аннотации и классы в
org.junit.jupiter.api. - Новые аннотации:
@BeforeAll,@AfterAll,@DisplayName. - Улучшенные assertions: Поддержка лямбда-выражений, группировка.
- Параметризованные тесты: Через
@ParameterizedTestс различными источниками данных (@CsvSource,@ValueSource). - Динамические тесты:
@TestFactoryдля генерации тестов в runtime.
Пример теста на JUnit 5:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;
import static org.junit.jupiter.api.Assertions.*;
class CalculatorTest {
@Test
@DisplayName("Сложение двух чисел")
void additionTest() {
assertEquals(4, Calculator.add(2, 2));
assertThrows(IllegalArgumentException.class,
() -> Calculator.add(null, 2));
}
}
Для новых проектов рекомендуется JUnit 5 из-за его гибкости и активного развития.
Ответ 18+ 🔞
Э, слушай, вот сидишь такой, пишешь свой код, и тут бац — нужно его протестировать. А вокруг все носятся с этим JUnit 5, он же Jupiter. Архитектура у них там, блядь, трёхэтажная, как у честного бизнесмена: Jupiter, Vintage, Platform. Всё разложено по полочкам, не то что в старом добром JUnit 4, где всё в одной куче валялось, как носки после командировки.
А если влез в какой-нибудь legacy-проект, который ещё твои деды писали, то там, ясное дело, JUnit 4. И приходится вспоминать, как это — писать @Before вместо @BeforeEach. Чувствуешь себя археологом, ёпта, который откапывает древние артефакты в виде assertEquals(expected, actual).
Так в чём же, сука, разница-то основная? Давай по пунктам, а то мозг заплыл:
- Архитектура. Я уже говорил — не одна библиотека, а целый конструктор.
Jupiter— это для новых тестов,Vintage— чтоб старые JUnit 4 тесты не выкидывать, аPlatform— чтоб вся эта ебля в IDE и сборщиках запускалась. Умно, чо. - Пакеты. Всё переехало. Раньше было
org.junit, а теперьorg.junit.jupiter.api. Запомнил? Нет? Ну и хуй с тобой, IDE сама подскажет, когда красным подчеркнёт. - Аннотации новые.
@BeforeAllи@AfterAll— это статические методы, которые один раз выполняются ДО и ПОСЛЕ ВСЕХ тестов. Не путать с@BeforeEach, который, как надоедливый комар, жужжит перед КАЖДЫМ тестом. А ещё есть@DisplayName— можно тест назвать человеческими словами, а неtestAdditionWhenParamsAreNullThrowsException, блядь. - Assertions. Тут вообще красота. Можно в
assertTrueлямбду запихнуть, и если тест сломается, то в ошибке сразу твоё кастомное сообщение выведется, а не простоexpected: true but was: false. Гениально и просто, как тапок по ебалу. - Параметризованные тесты. Это просто песня, а не фича. Раньше надо было городить огород, а сейчас навесил
@ParameterizedTest, накормил его данными через@CsvSourceили@ValueSource, и он сам, сука, нагенерирует кучу тест-кейсов. Красота! - Динамические тесты.
@TestFactory— это для совсем ебанутых сценариев, когда тесты прямо во время выполнения (runtime) генерируются. Сам не часто пользовался, но знать надо — вдруг начальству понравится слово "динамический".
Ну и примерчик, чтобы глаза замылились:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;
import static org.junit.jupiter.api.Assertions.*;
class CalculatorTest {
@Test
@DisplayName("Сложение двух чисел")
void additionTest() {
assertEquals(4, Calculator.add(2, 2));
assertThrows(IllegalArgumentException.class,
() -> Calculator.add(null, 2));
}
}
Видишь? Красиво, читаемо. assertThrows — это вообще лапочка, чтобы проверить, летит ли исключение, где надо.
Итог, блядь: если начинаешь новый проект — даже не думай, бери JUnit 5. Он гибкий, развивается, и с ним не стыдно. А JUnit 4... Ну, это как запасные кальсоны на случай, если в старом доме придётся ремонт делать. Есть — и хорошо.