07/11/2026

TestNG vs JUnit 5

Подробное сравнение тестовых фреймворков TestNG и JUnit 5 для Java QA Automation: аннотации, жизненный цикл, параметризация, параллельный запуск и топ-5 вопросов на собеседовании.

1. Краткая суть (чтобы рассказать на старте)

  • JUnit 5 — это современный стандарт, эволюция JUnit 4. Он модульный, гибкий, отлично интегрируется с экосистемой Java. Его архитектура состоит из трех частей: Jupiter (написание тестов), Platform (запуск и отчеты), Vintage (запуск старых тестов JUnit 3/4).
  • TestNG (Test Next Generation) — создан как улучшение JUnit (старых версий). Его главные фишки: строгая иерархия выполнения (Suite -> Test -> Class -> Method), удобная работа с testng.xml и "из коробки" мощный параллельный запуск. Часто используется в крупных Selenium-проектах.

2. Главные отличия (Топ для собеседования)

"В чем разница между JUnit 5 и TestNG?"

ФичаJUnit 5TestNG
ИерархияПлоская. Нет встроенного понятия "Suite".Строгая: Suite -> Test -> Class -> Method.
КонфигурацияКод + аннотации + junit-platform.properties.Код + аннотации + testng.xml (очень важно!).
Параллельный запускНастраивается через properties или аннотацию @Execution(CONCURRENT).Настраивается в testng.xml (parallel="methods") или аннотациями.
Параметризация@ParameterizedTest + источники (@CsvSource, @MethodSource).@DataProvider + @Test(dataProvider = "name").
Группировка@Tag("smoke") + фильтрация при запуске.groups = {"smoke"} в аннотации @Test + фильтрация в testng.xml.
Пропуск тестов@Disabled("reason") над методом или классом.@Test(enabled = false) или throw new SkipException().
РасширенияExtension Model (гибкий, можно перехватывать любой этап).Listeners (@Listeners), менее гибкие, чем в JUnit 5.
Assertionsorg.junit.jupiter.api.Assertions (нет assertAll в старых версиях, но есть в новых).org.testng.Assert (есть assertAll / SoftAssert из коробки).

3. Аннотации (Шпаргалка)

На собеседовании могут спросить: "Как изменится порядок выполнения, если добавить методы?"

JUnit 5: 1. @BeforeAll (один раз перед всеми тестами в классе, должен быть static) 2. @BeforeEach (перед каждым тестом) 3. @Test (сам тест) 4. @AfterEach (после каждого теста) 5. @AfterAll (один раз после всех тестов, static)

TestNG (Запомни эту пирамиду!): 1. @BeforeSuite / @AfterSuite (до/после всего запуска) 2. @BeforeTest / @AfterTest (до/после тестов, описанных в <test> в xml) 3. @BeforeClass / @AfterClass (до/после класса) 4. @BeforeMethod / @AfterMethod (до/после каждого @Test)

💡 Ловушка на интервью: В JUnit 5 нет @BeforeSuite. Если спросят, как сделать действие перед всем прогоном в JUnit 5, отвечай: "Нужно писать кастомное Extension (реализовать BeforeAllCallback) или использовать возможности CI/CD и testng.xml (если он используется для запуска JUnit через плагины)".

4. Топ-5 вопросов на собеседовании и ответы

В1: Как передать данные в тест (Параметризация)?

  • JUnit 5: Используем @ParameterizedTest. Данные берем из @ValueSource, @CsvSource, @EnumSource или из метода через @MethodSource.
  • TestNG: Создаем метод, возвращающий Object[][], помечаем его @DataProvider(name="myData"). В самом тесте пишем @Test(dataProvider="myData").

В2: Что такое Soft Assertions (Мягкие ассерты)?

  • Суть: Обычный Assert.assertEquals() падает сразу при несовпадении. Soft Assert проверяет все условия, собирает ошибки и падает только в конце (когда мы вызываем assertAll()).
  • JUnit 5:Assertions.assertAll(() -> assertEquals(...), () -> assertTrue(...));
  • TestNG:SoftAssert softAssert = new SoftAssert(); softAssert.assertEquals(...); softAssert.assertAll();

В3: Как запустить тесты параллельно?

  • TestNG: В testng.xml у тега <suite> пишем parallel="methods" (или classes, tests).
  • JUnit 5: В файле junit-platform.properties пишем junit.jupiter.execution.parallel.enabled = true и junit.jupiter.execution.parallel.mode.default = concurrent.

В4: Как пропустить тест в зависимости от условия?

  • TestNG: В @BeforeMethod или внутри теста бросаем throw new SkipException("Пропускаем, потому что...");.
  • JUnit 5: Используем Assumptions. Например, Assumptions.assumingThat(...) — если условие false, тест не падает (Fail), а пропускается (Skip/Abort).

В5: Что такое TestNG Listener?

  • Это интерфейс, который позволяет перехватывать события жизненного цикла теста (до старта, после падения, при пропуске). Чаще всего используется для создания скриншотов при падении теста (onTestFailure) или логирования в Allure. Подключается через @Listeners(MyListener.class).

💡 Лайфхак для собеседования: Если ты работала только с TestNG, а на проекте просят JUnit 5 (или наоборот), не паникуй. Скажи: "Я глубоко работала с [TestNG/JUnit 5], настраивала параллельные запуски и датапровайдеры. Архитектурно я понимаю разницу, и переход на другой фреймворк займет у меня пару дней, так как концепции (аннотации, жизненный цикл, ассерты) идентичны".