Можно ли объединить несколько тестов в один параметризованный тест
Что проверяют
Знаете ли вы механизм параметризации в современном JUnit и умеете ли решить, когда объединять тесты, а когда нет. Следом спрашивают, как передать сложные объекты вместо примитивов и как понять, на каком наборе тест упал.
Как отвечать
Да, если тесты отличаются только входными данными и ожидаемым результатом. В JUnit Jupiter для этого есть @ParameterizedTest из артефакта junit-jupiter-params (в spring-boot-starter-test он уже подключён). Источники данных:
@ValueSource: один аргумент из массива литералов, напримерints = {1, 2, 3};@CsvSource: несколько аргументов в строке, удобно для пар «вход и ожидание». Для большой таблицы есть@CsvFileSource;@MethodSource: статический метод возвращаетStream<Arguments>, так передаются объекты, списки, DTO;@EnumSource: прогон по всем значениям enum или по выбранным черезnames;@NullSource,@EmptySource,@NullAndEmptySource: граничные случаи для строк и коллекций.
Каждый набор становится отдельным запуском в отчёте, и падение одного не останавливает остальные. Задайте осмысленное имя через @ParameterizedTest(name = "{index}: {0} даёт {1}"), чтобы в CI было видно не только аргументы, но и смысл проверки.
Покажите, что знаете и старый способ: в JUnit 4 это @RunWith(Parameterized.class) с конструктором и методом под @Parameters, параметры задаются на весь класс. В новом коде его не используют. В TestNG аналог: @DataProvider.
Критерий объединения: одно действие и одна проверка с разными данными. Если внутри теста появляется if по параметру или ожидание исключения для части наборов, это разные сценарии. Ошибочные входы лучше вынести в отдельный параметризованный тест с assertThrows.
Где спотыкаются
Приводят пример на JUnit 4 как основной. В проекте на JUnit 5 это выдаёт, что вы давно не писали тесты.
Сливают в один тест разные сценарии и добавляют ветвление по флагу. Такой тест трудно читать, а упавший набор не объясняет, что сломалось.
Не знают правил @CsvSource. Разделитель по умолчанию запятая, пустое значение без кавычек превращается в null, а '' в пустую строку, и тест молча проверяет не то, что задумано.