Подробное сравнение тестовых фреймворков TestNG и JUnit 5 для Java QA Automation: аннотации, жизненный цикл, параметризация, параллельный запуск и топ-5 вопросов на собеседовании.
testng.xml и "из коробки" мощный параллельный запуск. Часто используется в крупных Selenium-проектах."В чем разница между JUnit 5 и TestNG?"
| Фича | JUnit 5 | TestNG |
|---|---|---|
| Иерархия | Плоская. Нет встроенного понятия "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. |
| Assertions | org.junit.jupiter.api.Assertions (нет assertAll в старых версиях, но есть в новых). | org.testng.Assert (есть assertAll / SoftAssert из коробки). |
На собеседовании могут спросить: "Как изменится порядок выполнения, если добавить методы?"
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 через плагины)".
В1: Как передать данные в тест (Параметризация)?
@ParameterizedTest. Данные берем из @ValueSource, @CsvSource, @EnumSource или из метода через @MethodSource.Object[][], помечаем его @DataProvider(name="myData"). В самом тесте пишем @Test(dataProvider="myData").В2: Что такое Soft Assertions (Мягкие ассерты)?
Assert.assertEquals() падает сразу при несовпадении. Soft Assert проверяет все условия, собирает ошибки и падает только в конце (когда мы вызываем assertAll()).Assertions.assertAll(() -> assertEquals(...), () -> assertTrue(...));SoftAssert softAssert = new SoftAssert(); softAssert.assertEquals(...); softAssert.assertAll();В3: Как запустить тесты параллельно?
testng.xml у тега <suite> пишем parallel="methods" (или classes, tests).junit-platform.properties пишем junit.jupiter.execution.parallel.enabled = true и junit.jupiter.execution.parallel.mode.default = concurrent.В4: Как пропустить тест в зависимости от условия?
@BeforeMethod или внутри теста бросаем throw new SkipException("Пропускаем, потому что...");.Assumptions. Например, Assumptions.assumingThat(...) — если условие false, тест не падает (Fail), а пропускается (Skip/Abort).В5: Что такое TestNG Listener?
onTestFailure) или логирования в Allure. Подключается через @Listeners(MyListener.class).💡 Лайфхак для собеседования: Если ты работала только с TestNG, а на проекте просят JUnit 5 (или наоборот), не паникуй. Скажи: "Я глубоко работала с [TestNG/JUnit 5], настраивала параллельные запуски и датапровайдеры. Архитектурно я понимаю разницу, и переход на другой фреймворк займет у меня пару дней, так как концепции (аннотации, жизненный цикл, ассерты) идентичны".