java что такое параметризированный тест

Unit-тестирование, детальное рассмотрение параметризованных тестов. Часть I

Доброго времени суток, коллеги.

Я решил поделиться своим видением на параметризованные юнит-тесты, как делаем это мы, и как возможно не делаете (но захотите делать) вы.

Хочется написать красивую фразу, о том что тестировать надо правильно, и тесты это важно, но до меня сказано и написано уже много материала, я лишь попробую резюмировать и осветить то, что по моему мнению людьми редко используется(понимается), на что в основном задвигается.

Основная цель статьи показать, как можно(и нужно) перестать захламлять свой юнит-тест кодом для создания объектов, и как декларативно создать тестовые данные, если одних mock(any()) не хватает, а таких ситуаций полно.

Создадим maven проект, добавим в него junit5, junit-jupiter-params и mokito

Чтоб не было совсем скучно начнем писать сразу с теста, как любят апологеты TDD, нам нужен сервис, который мы будем декларативно тестировать, подойдет любой, пускай это будет HabrService.

Создадим тест HabrServiceTest. В поле класса теста добавим ссылку на HabrService:

создадим сервис через ide (легким нажатием шортката), добавим на поле аннотацию @InjectMocks.

Приступаем непосредственно к тесту: HabrService в нашем небольшом приложении будет иметь один единственный метод handle(), который будет принимать один единственный аргумент HabrItem, и теперь наш тест выглядит так:

Добавим в HabrService метод handle(), который будет возвращать id нового поста на хабре после его модерации и сохранения в БД, и принимает тип HabrItem, так же создадим наш HabrItem, и теперь тест компилируется, но падает.

Дело в том что мы добавили проверку, на ожидаемое возвращаемое значение.

Также, я хочу убедиться, что в ходе вызова метода handle(), были вызваны ReviewService и PersistanceService, вызвались они строго друг за другом, отработали ровно по 1 разу, и никакие другие методы уже не вызывались. Иными словами вот так:

Добавим в поля класса класса reviewService и persistenceService, создадим их, добавим им методы makeRewiew() и makePersist() соответственно. Теперь все компилируется, но конечно же тест красный.

В контексте данной статьи, реализации ReviewService и PersistanceService не так уж важны, важна реализация HabrService, сделаем его чуть интересней чем он есть сейчас:

и с помощью конструкций when().then() замокируем поведение вспомогательных компонентов, в итоге наш тест стал вот таким и теперь он зеленый:

Макет для демонстрации мощи параметризованных тестов готов.

Добавим в нашу модель запроса к сервису HabrItem поле с типом хаба, hubType, создадим enum HubType и включим в него несколько типов:

а модели HabrItem добавим геттер и сеттер, на созданное поле HubType.

Предположим, что в недрах нашего HabrService спрятался switch, который в зависимости от типа хаба делает с запросом неведомое что-то, и в тесте мы хотим протестировать каждый из кейсов неведомого, наивная реализация метода выглядела бы так:

Можно сделать ее чуть красивей и удобней, сделав тест параметризированным и добавить в него в качестве параметр случайное значение из нашего enum, в итоге декларация теста станет выглядеть так:

красиво, декларативно, и все значения нашего enum обязательно будут задействованы при каком-нибудь очередном запуске тестов, у аннотации есть параметры, можем добавлять стратегии на include, exclude.

Но возможно я вас не убедил, что параметризованные тесты — это хорошо. Добавим в
исходный запрос HabrItem новое поле editCount, в которое будет записано количество тысяч раз, которое пользователи Хабра редактируют свою статью, перед тем как запостить, чтоб она вам хоть немного понравилась, и положим что где то в недрах HabrService есть какая то логика, которая делает неведомое что-то, в зависимости от того, насколько попыток автор постарался, что если я не хочу писать 5 или 55 тестов на все возможные варианты editCount, а хочу протестировать декларативно, и где то в одном месте сразу обозначить все значения которые я хотел бы проверить. Нет ничего проще, и воспользовавшись api параметризованных тестов получим в декларации метода что то такое:

Налицо проблема, мы хотим собирать в параметрах тестового метода сразу два значения декларативно, можно использовать еще один прекрасный метод параметризованных тестов @CsvSource, отлично подойдет для того чтоб протестировать несложные параметры, с несложным выходным значением(крайне удобен в тестировании утилитных классов), но что если объект станет гораздо сложней? Скажем, в нем будет порядка 10 полей, причем не только примитивы и джава-типы.

На помощь приходит аннотация @MethodSource, наш тестового метода стал ощутимо короче и в нем нет больше сеттеров, а источник входящего запроса подается в тестовый метод параметром:

в аннотации @MethodSource указана строка generateSource, что это? это название метода, который соберет для нас нужную модель, его декларация будет выглядеть так:

для удобства формирование стрима аргументов nextStream я вынесес в отдельный утилитный тестовый класс:

Теперь в при запуске теста, в параметр тестового метода декларативно будет добавляться модель запроса HabrItem, причем запускаться тест будет столько раз, сколько аргументов сгененрирует наша тестовая утилита, в нашем случае от 1 до 10.

Это может быть особо удобно, если модель в стриме аргументов собирается не хардкодом, как в нашем примере, а с помощью рандомайзеров.(да здравствует плавающие тесты, но ведь если они есть — есть и проблема).

По моему уже все супер, в тесте теперь описано только поведение наших заглушек, и ожидаемые результаты.

Но вот незадача, в модель HabrItem добавляется новое поле, text, массив строк, которое может быть очень большим или не очень, неважно, главное то, что мы не хотим захламять наши тесты, нам не нужны рандомные данные, мы хотим строго определенную модель, с конкретными данными, собирать ее в тесте или где либо еще — мы не хотим. Было бы круто, если бы можно было взять тело json запроса откуда угодно, например из постмана, сделать на его основе моковый файл и в тесте формировать модель декларативно, указав лишь путь к json файлу с данными.

Отлично. Используем аннотацию @JsonSource, которая будет принимать параметр path, с относительным путем к файлу и целевой класс. Черт! В параметризованных тестах нет такой аннотации, а хотелось бы.

Давайте напишем сами.

Обработкой всех аннотаций идущих в комплекте с @ParametrizedTest в junit занимаются ArgumentsProvider, мы напишем свой собственный JsonArgumentProvider:

MockDataProvider, это класс, для парсинга моковых json файлов, его реализация крайне простая:

Моковый провайдер готов, провайдер аргументов для нашей аннотации тоже, осталось добавить саму аннотацию:

Ура. Наша аннотация готова к употреблению, тестовый метод стал таким:

в моковом json мы можем наплодить сколь угодно и очень быстро пачку нужным нам объектов, и нигде отныне нет отвлекающего от сути теста кода, по формированию тестовых данных, конечно часто можно обойтись моками, но далеко не всегда.

Резюмируя, я хотел бы сказать следующее: часто мы работаем как привыкли работать, годами, не задумываясь о том, что некоторые вещи можно сделать красиво и просто, зачастую, используя стандартный api библиотек, которые мы юзаем годами, но не знаем всех их возможностей.

Источник

Тестирование в Java. TestNG

java что такое параметризированный тест. Смотреть фото java что такое параметризированный тест. Смотреть картинку java что такое параметризированный тест. Картинка про java что такое параметризированный тест. Фото java что такое параметризированный тест
Наверняка все знакомы с таким понятием как test-driven development(TDD). Наряду с ним также существует такое понятие, как data-driven testing(DDT, не в обиду Шевчуку) — техника написания тестов, при которой данные для тестов хранятся отдельно от самих тестов. Они могут храниться в базе данных, файле, генерироваться во время исполнения теста. Это очень удобно, так как один и тот же функционал тестируется на различных наборах данных, при этом добавление, удаление или изменение этих данных максимально упрощено.

В предыдущей статье я рассмотрел возможности JUnit-а. Там примерами такого рода подхода могут служить запускалки Parameterized и Theories, в обоих случаях один тест-класс может содержать только один такой параметризированный тест(в случае Parameterized несколько, но все они будут использовать одни и те же данные).

В этой статье я заострю внимание на тестовом фреймворке TestNG. Многие уже слышали это название, и перейдя на него, вряд ли желают вернуться к JUnit-у(хотя это только предположение).

Основные возможности

Итак, что же здесь есть? Как и в JUnit 4 тесты описываются с помощью аннотаций, также поддерживаются тесты, написанные на JUnit 3. Есть возможность вместо аннотаций использовать доклет.

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

У каждого участника этой иерархии могут иметься before и after конфигураторы. Запускается это все в таком порядке:

Напишем к ней тест в стиле JUnit-a(не стоит рассматривать данный пример как руководство к написанию тестов на TestNG):

Параметризированные тесты

Напишем этот же тест другим способом:

Проще? Конечно, данные хранятся отдельно от самого теста. Удобно? Конечно, можно добавлять тесты, добавляя всего лишь строчку в метод parseLocaleData.

В этом случае задаются параметры dataProviderClass и dataProvider. Метод, возвращающий тестовые данные должен быть static.

Кроме описанного выше есть еще один способ параметризировать тесты. Нужный метод аннотируется с помощью @Parameters, где указываются имена всех необходимых параметров. Некоторые из параметров можно зааннотировать с помощью @Optional с указанием значения по умолчанию(если не указать, то будут использоваться значения по умолчанию для примитивов, либо null для всех остальных типов). Значения параметров хранятся в конфигурации TestNG(которая будет рассмотрена позже). Пример:

В данном случае метод setUpDataSource будет принимать в качестве параметров настройки соединения с БД, причем параметры username и password опциональны, с заданными значениями по умолчанию. Очень удобно использовать с данными, общими для всех тестов(ну или почти всех), например, как в примере настройки соединения с БД.

Ну и в завершение следует сказать пару слов о фабриках, которые позволяют создавать тесты динамически. Также, как и сами тесты, могут быть параметризированы с помощью @DataProvider либо @Parameters:

Вариант с @Parameters:

Многопоточность

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

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

Данный тест будет выводить нечто вроде:

Без этого параметра будет что-то вроде:

Дополнительные возможности

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

Похожее поведение будет наблюдаться также если указать зависимости у теста, например, добавим в наш тест:

Обычно это удобно, когда один тест зависит от другого, например, Утилита1 использует Утилиту0, если Утилита0 работает неправильно, то нет смысла тестировать Утилиту1. С другой стороны зависимости также удобно использовать в @Before, @After методах, особенно для связи базового теста с наследующимся, причем иногда бывает необходимо сделать так, чтобы даже если метод A свалился, а метод B зависит от него, метод B все равно вызывался. В этом случае устанавливаем параметр alwaysRun в true.

Внедрение зависимостей

Хочу порадовать любителей фреймворка от «корпорации добра» Guice. В TestNG есть встроенная поддержка последнего. Выглядит это так:

Все, что надо — зааннотировать нужный класс с помощью @Guice и указать в параметре modules все необходимые guice-модули. Далее в тест классе можно уже использовать внедрение зависимостей, используя @Inject.

Добавлю еще, что любителям других подобных фреймворков не стоит расстраиваться, так как у них обычно есть своя поддержка TestNG, например, у Spring-а.

Расширение функционала

Конфигурация

Теперь перейдем к конфигурации тестов. Простейший способ запустить тесты выглядит примерно так:

Но чаще всего для запуска тестов используется XML либо YAML конфигурация. XML конфигурация выглядит примерно так:

Аналогичная YAML конфигурация:

Тогда для запуска тестов нужно будет сделать следующее:

Хотя, наверное, программный запуск тестов это излишне, т.к. для этого можно использовать возможности IDE.

В данном примере тест будет включать в себя только тесты не относящиеся к группе integration.

Еще тесты могут включать в себя тест-классы, которые в свою очередь могут включать/исключать в себя тест-методы.

Вывод

Это не все, что можно сказать по этому замечательному фреймворку, все охватить в одной статье очень трудно. Но я постарался раскрыть основные моменты его использования. Тут, конечно, можно было рассказать немного больше про механизм слушателей, про интеграции с другими фреймворками, про конфигурацию тестов, но тогда статья превратилась бы в книгу, да и не знаю я всего. Но, надеюсь, эта статья была кому-то полезна и то, что было сказано, сподвигнет некоторых читателей на использование TestNG, или хотя бы на DDT технику написания тестов.

Примеры можно найти здесь, различные статьи здесь.

Источник

Учимся параметризировать тесты в JUnit

java что такое параметризированный тест. Смотреть фото java что такое параметризированный тест. Смотреть картинку java что такое параметризированный тест. Картинка про java что такое параметризированный тест. Фото java что такое параметризированный тест

Начиная с 4-й версии, в JUnit введена параметризация тестов. Она позволяет значительно уменьшить избыточность кода. Разберемся, как работать с параметризацией.

По определению, параметризация это функция “позволяющая запускать тестовый метод каждый раз с разными параметрами”.

В конце узнаем о некоторых полезностях, которые можно применять в своей практике, на практическом примере.

1. Начинаем

Для начала нужно разбираться в Spring Boot и JUnit.

Итак, с чем будем работать:

1.1. Добавляем зависимость JUnit

Настраиваем проект (возможно стоит ознакомиться с указаниями, как это делать), далее добавляем в pom.xml такие строчки:

Первая из зависимостей включает не только JUnit, но и еще пару библиотек, которые которые могут понадобиться для тестирования нашего приложения: mockito и hamcrest. Hamcrest будет задействован для получения провайдеров аргументов (далее объясню, что это).

2. Настраиваем сценарий

2.1. Работаем с одним аргументом

Представим, что надо работать с функцией, которая проверяет введенный возраст, больше ли он, чем 21 год.

Теперь создаем тест, в котором проверяем, выдаст ли ошибку в ответ на другие аргументы.

Сейчас нам нужно ввести аннотации @ParameterizedTest и @ValueSource, чтобы JUnit “понимал”, что будут передаваться разные аргументы. Такие аннотации позволяют применять аргументы самых разных типов, а именно: short, byte, int, long, float, double, char, boolean, string, и даже class.

Мы передали 4 аргумента, и это значит, что тест запустится 4 раза. В первой итерации переменная age примет значение 10, далее 0, 15, 20.

После завершения тестов увидим в окне Test Results результат каждой итерации.

2.2. Передача нескольких аргументов

Теперь создадим простую функцию, умножающую два целых числа.

Представим, что нужно протестировать эту функцию, передавая в нее два аргумента со значением 2. Их умножение должно быть равно 4 (если правила арифметики не поменялись).

Пока видим, что в тесте без проблем. Но есть вещи, которые нужно иметь в виду.

Хороший тестировщик знает, что такой простой тест не охватывает все возможные варианты, нам надо протестировать параметры так, чтобы код приложения работал при любых условиях. Например, в данном случае результат не должен быть равным нулю или отрицательным.

Поэтому и нужны параметризованные тесты с несколькими аргументами. Смотрим на код ниже.

Здесь видим, что есть какое-то @CsvSource вслед за @ParameterizedTest.

Первая итерация получит аргументы 2, 3, 6, которые “привязаны” к сигнатуре метода, простым их объявлением.

Важная вещь которую нужно иметь в виду: аргументы “привязываются” точно в том порядке, в котором передавались. А именно:

Здесь может возникнуть вопрос, почему передается String, если метод calculatedTotalPrice предполагает только int-аргументы? А вот здесь видна полезность JUnit.

Иногда это называют “преобразованием аргументов”, или приведением их типов (Argument Conversion). Эта тема выходит за рамки обзорной статьи, но ее стоит упомянуть.

Кратко посмотрим, что делает такое преобразование:

Должно быть, впечатляет. Это автоматическая конвертация строкового формата в LocalDate. Желательно сверяться с документацией, работая с преобразованием типов.

2.3. Работаем с CSV-файлом

В предыдущем примере мы задействовали @CsvSource, несмотря на то что передали как аргумент строковое значение (String). Но бывает проблема, когда данных очень много, или если нужно тестировать много сценариев. Это превращается в хаос, тест нечитаемый.

Но есть способ сделать CSV-файл “правильным”.

Сперва создадим файл testData.csv в папке src/test/resources, и вставим в него такие строчки:

Мы добавили аннотацию @CsvFileSource, имеющую аргумент “resources”, который должен быть добавлен в адрес CSV-файла. (Если этот файл расположен в папке по умолчанию — src/test/resources — то можно указать только его название с расширением, файл будет найден автоматически).

2.4. Источник Enum-данных

Аннотация @EnumSource говорит о передаче данных из Enum. Обычно это бывает при тестировании бизнес-логики.

2.5. Аннотация MethodSource

Иногда может понадобиться передать несколько параметров (их набор) в несколько тестов. Для этого придумана аннотация @MethodSource.

Она загружает внешнюю функцию, выступающей в роли “поставщика аргументов”. Так можно передать набор параметров в несколько тестов.

Функция DataProvider может добавляться к любому пакету, нужно ввести полный путь к нему.

Здесь все, что нужно сделать, это декларировать пакет с этой функцией, вставить символ хэштега #, и затем название функции, и это будет аргумент аннотации.

3. Бонус.

Можно кастомизировать отображаемое имя тестов.

Как мы помним, в нашем тесте было:

При его запуске увидим следующее:

Вывод можно визуально приукрасить, следующими тегами:

Все что нужно сделать, это передать аргумент name внутри @parametrizedTest.

Надеемся, материал был не только сложным, но и полезным.

В.Нобрэ — тестировщик в компании PicPay (финтех)

Источник

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

1. Обзор

JUnit 5, следующее поколение JUnit, облегчает написание тестов разработчика с новыми и блестящими функциями.

Одной из таких функций является р arameterized тесты. Эта функция позволяет нам многократно выполнять один метод тестирования с разными параметрами.

В этом руководстве мы собираемся подробно изучить параметризованные тесты, так что приступим!

2. Зависимости

Чтобы использовать параметризованные тесты JUnit 5, нам необходимо импортировать артефакт junit-jupiter-params с платформы JUnit. Это означает, что при использовании Maven мы добавим в наш pom.xml следующее :

Кроме того, при использовании Gradle мы укажем его немного иначе:

3. Первое впечатление

Допустим, у нас есть существующая функция полезности, и мы хотели бы быть уверены в ее поведении:

Параметризованные тесты похожи на другие тесты, за исключением того, что мы добавляем аннотацию @ParameterizedTest :

Средство выполнения тестов JUnit 5 выполняет этот тест, а следовательно, и метод isOdd шесть раз. И каждый раз он присваивает другое значение из массива @ValueSource параметру числового метода.

Итак, этот пример показывает нам две вещи, которые нам нужны для параметризованного теста:

Есть еще одна вещь, которая не очевидна в этом примере, так что следите за обновлениями.

4. Источники аргументов

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

4.1. Простые ценности

Например, предположим, что мы собираемся протестировать наш простой метод isBlank :

Мы ожидаем, что этот метод вернет истину для null для пустых строк. Итак, мы можем написать параметризованный тест вроде следующего, чтобы подтвердить это поведение:

Как мы видим, JUnit запускает этот тест два раза и каждый раз присваивает один аргумент из массива параметру метода.

Одним из ограничений источников значений является то, что они поддерживают только следующие типы:

4.2. Нулевые и пустые значения

Начиная с JUnit 5.4, мы можем передать одно значение null параметризованному методу тестирования, используя @NullSource:

Точно так же мы можем передавать пустые значения с помощью аннотации @EmptySource :

Чтобы передать как нулевые, так и пустые значения, мы можем использовать составленную аннотацию @NullAndEmptySource :

In order to pass a few more empty string variations to the parameterized test, we can combine @ValueSource, @NullSource, and @EmptySource together:

4.3. Enum

In order to run a test with different values from an enumeration, we can use the @EnumSource annotation.

For example, we can assert that all month numbers are between 1 and 12:

Or, we can filter out a few months by using the names attribute.

How about asserting the fact that April, September, June, and November are 30 days long:

By default, the names will only keep the matched enum values. We can turn this around by setting the mode attribute to EXCLUDE:

In addition to literal strings, we can pass a regular expression to the names attribute:

Quite similar to @ValueSource, @EnumSource is only applicable when we’re going to pass just one argument per test execution.

4.4. CSV Literals

Suppose we’re going to make sure that the toUpperCase() method from String generates the expected uppercase value. @ValueSource won’t be enough.

In order to write a parameterized test for such scenarios, we have to:

So, we need argument sources capable of passing multiple arguments. The @CsvSource is one of those sources:

The @CsvSource accepts an array of comma-separated values and each array entry corresponds to a line in a CSV file.

This source takes one array entry each time, splits it by comma and passes each array to the annotated test method as separate parameters. By default, the comma is the column separator but we can customize it using the delimiter attribute:

Now it’s a colon-separated value, still a CSV!

4.5. CSV Files

Instead of passing the CSV values inside the code, we can refer to an actual CSV file.

For example, we could use a CSV file like:

We can load the CSV file and ignore the header column with @CsvFileSource:

The resources attribute represents the CSV file resources on the classpath to read. And, we can pass multiple files to it.

The numLinesToSkip attribute represents the number of lines to skip when reading the CSV files. By default, @CsvFileSource does not skip any lines, but this feature is usually useful for skipping the header lines, like we did here.

Just like the simple @CsvSource, the delimiter is customizable with the delimiter attribute.

In addition to the column separator:

4.6. Method

The argument sources we’ve covered so far are somewhat simple and share one limitation: It’s hard or impossible to pass complex objects using them!

One approach to providing more complex arguments is to use a method as an argument source.

Let’s test the isBlank method with a @MethodSource:

The name we supply to @MethodSource needs to match an existing method.

So let’s next write provideStringsForIsBlank, a static method that returns a Stream of Arguments:

Here we’re literally returning a stream of arguments, but it’s not a strict requirement. For example, we can return any other collection-like interfaces like List.

If we’re going to provide just one argument per test invocation, then it’s not necessary to use the Arguments abstraction:

When we don’t provide a name for the @MethodSource, JUnit will search for a source method with the same name as the test method.

Sometimes it’s useful to share arguments between different test classes. In these cases, we can refer to a source method outside of the current class by its fully-qualified name:

Using the FQN#methodName format we can refer to an external static method.

4.7. Custom Argument Provider

Another advanced approach to pass test arguments is to use a custom implementation of an interface called ArgumentsProvider:

Then we can annotate our test with the @ArgumentsSource annotation to use this custom provider:

Let’s make the custom provider a more pleasant API to use with a custom annotation!

4.8. Custom Annotation

How about loading the test arguments from a static variable? Something like:

Actually, JUnit 5 does not provide this! However, we can roll our own solution.

First off, we can create an annotation:

Then we need to somehow consume the annotation details and provide test arguments. JUnit 5 provides two abstractions to achieve those two things:

So, we next need to make the VariableArgumentsProvider class read from the specified static variable and return its value as test arguments:

And it works like a charm!

5. Argument Conversion

5.1. Implicit Conversion

Let’s re-write one of those @EnumTests with a @CsvSource:

This shouldn’t work, right? But, somehow it does!

So, JUnit 5 converts the String arguments to the specified enum type. To support use cases like this, JUnit Jupiter provides a number of built-in implicit type converters.

The conversion process depends on the declared type of each method parameter. The implicit conversion can convert the String instances to types like:

5.2. Explicit Conversion

Sometimes we need to provide a custom and explicit converter for arguments.

Suppose we want to convert strings with the yyyy/mm/dd format to LocalDate instances. First off, we need to implement the ArgumentConverter interface:

Then we should refer to the converter via the @ConvertWith annotation:

6. Argument Accessor

By default, each argument provided to a parameterized test corresponds to a single method parameter. Consequently, when passing a handful of arguments via an argument source, the test method signature gets very large and messy.

One approach to address this issue is to encapsulate all passed arguments into an instance of ArgumentsAccessor and retrieve arguments by index and type.

For example, let’s consider our Person class:

Then, in order to test the fullName() method, we’ll pass four arguments: firstName, middleName, lastName, and the expected fullName. We can use the ArgumentsAccessor to retrieve the test arguments instead of declaring them as method parameters:

Here, we’re encapsulating all passed arguments into an ArgumentsAccessor instance and then, in the test method body, retrieving each passed argument with its index. In addition to just being an accessor, type conversion is supported through get* methods:

7. Argument Aggregator

Using the ArgumentsAccessor abstraction directly may make the test code less readable or reusable. In order to address these issues, we can write a custom and reusable aggregator.

To do that, we implement the ArgumentsAggregator interface:

And then we reference it via the @AggregateWith annotation:

The PersonAggregator takes the last three arguments and instantiates a Person class out of them.

8. Customizing Display Names

By default, the display name for a parameterized test contains an invocation index along with a String representation of all passed arguments, something like:

However, we can customize this display via the name attribute of the @ParameterizedTest annotation:

April is 30 days long surely is a more readable display name:

The following placeholders are available when customizing the display name:

9. Conclusion

In this article, we’ve explored the nuts and bolts of parameterized tests in JUnit 5.

We learned that parameterized tests are different from normal tests in two aspects: they’re annotated with the @ParameterizedTest, and they need a source for their declared arguments.

Also, by now, we should now that JUnit provides some facilities to convert the arguments to custom target types or to customize the test names.

Как обычно, образцы кода доступны в нашем проекте GitHub, поэтому обязательно ознакомьтесь с ним!

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *