Как стать автором
Обновить

Как мы создаем параметризованные автотесты с JUnit 5

Уровень сложностиПростой
Время на прочтение6 мин
Количество просмотров398

Параметризованные автотесты — это удобный инструмент, который помогает тестировать программное обеспечение быстрее и эффективнее. Вместо написания множества однотипных тестов с разными входными данными, можно использовать один тестовый метод, подставляя в него разные параметры. Это упрощает код и делает его более удобным в поддержке. JUnit 5, популярный фреймворк для тестирования Java-приложений, предлагает множество возможностей для работы с параметризованными тестами, делая процесс тестирования гибче и удобнее.

Что такое параметризованные автотесты

Параметризованные тесты позволяют запускать один и тот же тестовый метод с разными входными значениями. В классическом подходе для каждого сценария создается отдельный тест, что ведет к дублированию кода. С параметризованными тестами достаточно один раз определить логику, а затем подставлять разные данные. Это делает тесты более читаемыми и удобными в поддержке.

JUnit 5 значительно улучшил работу с параметризованными тестами по сравнению с JUnit 4. Ранее приходилось параметризовать весь тестовый класс, что было не всегда удобно. Теперь можно параметризовать отдельные методы, комбинируя их с обычными тестами. Также расширился список источников данных: дополнительно можно использовать CSV-файлы, методы с потоками данных и другие варианты.

Зачем нужны параметризованные тесты

Вот основные преимущества параметризованных тестов:

  • Меньше дублирования кода. Один метод тестирует сразу несколько сценариев. Соответственно, это уменьшает объем кода и снижает вероятность ошибок, связанных с дублированием.

  • Легче покрывать разные случаи, например пограничные условия и особые случаи. Можно быстро провести новый тест, просто добавив данные.

  • Экономия времени. Создание и поддержка тестов занимает меньше времени.

  • Удобочитаемость. Четкое разделение логики теста и тестовых данных. Более того, в CSV-файлах, данные доступны для анализа и редактирования даже для тех членов команды, которые не являются разработчиками.

  • Гибкость. Можно тестировать разные входные данные без изменения самого теста.

  • Системность. Метод стимулирует мыслить в терминах наборов данных и сценариев, а не отдельных вызовов методов, что способствует более полному охвату возможных ситуаций.

Как настроить JUnit 5 для параметризованных тестов

Чтобы использовать параметризованные тесты в JUnit 5, сначала добавьте в проект соответствующую зависимость. Актуальная версия зависимости доступна по ссылке https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter

Для Maven:

<dependency>

    <groupId>org.junit.jupiter</groupId>

    <artifactId>junit-jupiter</artifactId>

    <version>*Последняя версия*</version>

    <scope>test</scope>

</dependency>

Для Gradle:

testImplementation 'org.junit.jupiter:junit-jupiter:*Последняя версия*'

Основная аннотация для параметризованных тестов — @ParameterizedTest. Она заменяет стандартную @Test и указывает, что метод может запускаться несколько раз с различными наборами параметров.

Источники данных для параметризованных тестов

JUnit 5 поддерживает несколько способов передачи массивов данных в тесты.

@ValueSource — простые значения

Если нужно передать массив простых значений (числа, логические значения, строки), используйте @ValueSource:

@ParameterizedTest

@ValueSource(strings = {"apple", "banana", "orange"})

void testFruitNames(String fruit) {

    assertNotNull(fruit);

    assertTrue(fruit.length() > 0);

}

Этот тест запустится три раза: для каждого значения из массива.

@EnumSource — для перечислений

Если тест использует значения перечислений, поможет @EnumSource:

enum DayOfWeek {

    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY

}

@ParameterizedTest

@EnumSource(DayOfWeek.class)

void testDaysOfWeek(DayOfWeek day) {

    assertNotNull(day);

}

Тест выполнится для всех значений DayOfWeek.

@MethodSource — передача данных из метода

Если проще создавать сложные наборы тестовых данных программным путем, то стоит воспользоваться @MethodSource:

@ParameterizedTest

@MethodSource("provideTestData")

void testWithMethodSource(String input, int expected) {

    assertEquals(expected, input.length());

}

 

static Stream<Arguments> provideTestData() {

    return Stream.of(

        Arguments.of("apple", 5),

        Arguments.of("banana", 6),

        Arguments.of("orange", 6)

    );

}

Тест выполнится три раза, получая данные, в данном случае, из метода provideTestData.

Использование CSV-файлов для параметризации тестов

Если у вас много тестовых данных, удобнее хранить их в CSV-файле. JUnit 5 поддерживает это с помощью @CsvFileSource.

Пример CSV-файла (test-data.csv):

input,expected

apple,5

banana,6

orange,6

Использование в тесте:

@ParameterizedTest

@CsvFileSource(resources = "/test-data.csv", numLinesToSkip = 1)

void testWithCsvFileSource(String input, int expected) {

    assertEquals(expected, input.length());

}

Здесь тест будет загружать данные из test-data.csv, расположенного в корне ресурсов проекта (папка resources), и запускаться три раза.

Имена переменных в методе (input, expected) не обязательно должны совпадать с именами столбцов в CSV-файле (их может не быть вовсе, тогда нет необходимости указывать значение numLinesToSkip). JUnit сопоставляет значения по порядку: первый столбец с первым параметром, второй столбец — со вторым, и так далее.

Комментарии в CSV

Вариант 1. Строки, начинающиеся с #, будут пропущены:

input,expected

apple,5

# banana,6 (этот тест временно отключен)

orange,6

Вариант 2. Параметр numLinesToSkip — позволяет пропустить заданное количество строк в начале файла. Это полезно, когда CSV-файл содержит заголовки столбцов или какие-либо вводные данные, которые не должны обрабатываться как тестовые случаи.

Например:

@ParameterizedTest

@CsvFileSource(resources = "/test-data.csv", numLinesToSkip = 2)

void testWithSkippedLines(String input, int expected) {

    assertEquals(expected, input.length());

}

В этом примере будут пропущены первые две строки CSV-файла.

Настройка разделителей

По умолчанию используется запятая, но можно задать другой разделитель. Для этого предусмотрены параметры delimiter и delimiterString (для многосимвольных разделителей):

@ParameterizedTest

@CsvFileSource(

    resources = "/data-with-custom-delimiter.csv",

    numLinesToSkip = 1, 

    delimiter = ';',

    delimiterString = "||"

)

void testWithCustomDelimiter(String input, String expected) {

    assertEquals(expected, input.length());

}

Использование нескольких файлов

Можно загружать данные сразу из нескольких файлов:

@ParameterizedTest

@CsvFileSource(

    resources = {"/data-set-1.csv", "/data-set-2.csv"},

    numLinesToSkip = 1

)

void testWithMultipleFiles(String input, String expected) {

    assertEquals(expected, input.length());

}

Пропуск первых строк при этом, регулируемый параметром numLinesToSkip, применяется к каждому файлу.

Работа с кодировками

Для работы с файлами в различных кодировках и с разными разделителями строк предусмотрены параметры encoding и lineSeparator:

@ParameterizedTest

@CsvFileSource(

    resources = "/data-in-windows-encoding.csv",

    numLinesToSkip = 1,

    encoding = "Cp1251",

    lineSeparator = "\r\n"

)

void testWithCustomEncodingAndLineSeparator(String input, String expected) {

    assertEquals(expected, input.length());

}

Оформление тестов для отчетности

При генерации отчетов (например, в Allure Reports) для параметризованных тестов лучше использовать свой специфичный параметр name, который поддерживает различные способы использования тестовых данных: {index} для указания индекса текущей итерации, {arguments} — всех аргументов тестового метода, и {0}, {1}, ... — для использования конкретных аргументов по их индексам.

Заключение

Параметризованные тесты в JUnit 5 помогают упростить и ускорить тестирование. Они сокращают дублирование кода, упрощают поддержку тестов и делают процесс тестирования гибким. Возможность загружать тестовые данные из CSV-файлов позволяет четко разделять логику тестов и входные данные.

Если использовать параметризованные тесты правильно, это поможет сделать ваш код более надежным, а процесс тестирования — более прозрачным и удобным.

Теги:
Хабы:
+2
Комментарии0

Публикации

Истории

Ближайшие события

19 марта – 28 апреля
Экспедиция «Рэйдикс»
Нижний НовгородЕкатеринбургНовосибирскВладивостокИжевскКазаньТюменьУфаИркутскЧелябинскСамараХабаровскКрасноярскОмск
22 апреля
VK Видео Meetup 2025
МоскваОнлайн
23 апреля
Meetup DevOps 43Tech
Санкт-ПетербургОнлайн
24 апреля
VK Go Meetup 2025
Санкт-ПетербургОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань
14 мая
LinkMeetup
Москва
5 июня
Конференция TechRec AI&HR 2025
МоскваОнлайн
20 – 22 июня
Летняя айти-тусовка Summer Merge
Ульяновская область