junit jupiter что это

10 интересных нововведений в JUnit 5

В минувшее воскресенье Sam Brannen анонсировал выход JUnit 5! Ура!

Поздравляю всех участников @JUnitTeam а также всех, кто использует JUnit в своей работе! Давайте посмотрим, что же нам приготовили в этом релизе.

Содержание

1. Введение

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage (← офф.сайт).

JUnit Platform — фундаментальная основа для запуска на JVM фреймворков для тестирования. Платформа предоставляет TestEngine API, для разработки фреймворков (для тестирования), которые могут быть запущены на платформе. Кроме этого, в платформе имеется Console Launcher для запуска платформы из коммандной строки а также для запуска любого JUnit 4 Runner’а на платформе. Уже, кстати, есть плагины для Gradle и Maven.

JUnit Jupiter — сердце JUnit 5. Этот проект предоставляет новые возможности для написания тестов и создания собственных расширений. В проекте реализован специальный TestEngine для запуска тестов на ранее описанной платформе.

JUnit Vintage — поддержка легаси. Определяется TestEngine для запуска тестов ориентированных на JUnit 3 и JUnit 4.

1. Начало работы

2. Обзор нововведений

А теперь наконец-то перейдем к примерам!

2.1. public — всё
JUnit больше не требует, чтобы методы были публичными.

2.2. Продвинутый assert
Опциональное сообщение сделали последним аргументом.

Добавили специальный метод для логической группировки тестов.

Появился метод для работы с Iterable.

Добавили интересный метод для сравнения набора строк. Поддерживаются регулярные выражения!

2.3. Работа с исключениями
Работа с исключениями стала более линейной.

2.4. Новый Test
JUnit 5 привнес новую аннотацию Test, которая находится в пакете org.junit.jupiter.api.Test. В отличии от четвертой версии, новая аннотация служит исключительно маркером.

Новая аннотация выглядит так.

2.5. Новые базовые аннотации
В пятой версии добавили новые базовые аннотации.

2.6. Вложенные классы
Аннотация @Nested позволяет использовать внутренние классы при разработке тестов, что позволяет иногда более удобным способом группировать/дополнять тесты.

2.7. Разделяемый инстанс класса для запуска тестов
Для гарантии независимости и изоляциии тестов JUnit во всех предыдущих версиях всегда создавал по инстансу на тест (т.е. на каждый запуск метода отдельный инстанс). В пятой версии такое поведение можно изменить используя новую аннотацию @TestInstance(Lifecycle.PER_CLASS). В таком случае инстанс будет создан только один раз и будет переиспользован для запуска всех тестов, определенных внутри этого класса.

2.8. Автоматический повторный запуск теста
Еще одна приятная добавка! Аннотация @RepeatedTest сообщает JUnit, что данный тест нужно запустить несколько раз. При этом, каждый такой вызов будет независимым тестом, а значит для него будут работать аннотации @BeforeAll, @BeforeEach, @AfterEach и @AfterAll.

Стоит отметить, что можно настроить дополнительный вывод информации о запусках теста. Например, показывать номер запуска. За это отвечают специальные константы определенные внутри этой же аннотации.

2.9. Параметризированные тесты
Параметризированные тесты позволяют запускать тест несколько раз с различными входными данными. На данный момент поддерживаются только данные примитивных типов: int, long, double, String. Но не стоит отчаиваться! JUnit 5 определяет несколько дополнительных аннотаций для указания источника данных для параметризированных тестов. Итак, начнём!

Еще один вдохновляющий пример с @ValueSource.

Пример с разбором CSV.

Пример с источником данных.

Еще больше крутых примеров можно найти на официальном сайте в разделе 3.13. Parameterized Tests.

2.10. Аннотированные default методы в интерфейсах
JUnit теперь умеет работать с default методами в интерфейсах! Вот один из официальных примеров применения этого нововведения. Предлагаю посмотреть интересный пример с Equals Contract.

Заключение

Очень здорово, что популярный фреймворк для тестирования решается на такие серьезные эксперименты с API и старается идти в ногу со временем!

Еще много чего интересного осталось за рамками этой статьи. Например, отдельного обзора заслуживает механизм расширений, предоставляемый JUnit 5.
Спасибо за внимание!

Источник

Полное руководство по расширениям JUnit 5

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

СОДЕРЖАНИЕ

Что такого хорошего в JUnit 5?

Архитектура JUnit 5

Как зарегистрировать расширения JUnit 5

Условное выполнение теста JUnit 5 с аннотациями

Как создать расширения JUnit 5 путем реализации TestInstanceFactory

Как протестировать обратные вызовы жизненного цикла в JUnit 5

Постобработка тестового экземпляра в JUnit 5

Обратный вызов перед уничтожением тестового экземпляра в JUnit 5

Разрешение параметра в JUnit 5

Обработка исключений в JUnit 5

Сторонние расширения фреймворка в JUnit 5

Что такого хорошего в JUnit 5?

Если вы использовали фреймворк JUnit 4, вы согласитесь, что существуют ограниченные (или минимальные) возможности расширения или настройки фреймворка JUnit 4. Это одно из самых узких мест в этой версии фреймворка JUnit. В JUnit 4 такие расширения, как Runners, можно создавать, просто аннотируя тестовый класс с помощью @RunWith (MyRunner.class), чтобы JUnit мог их использовать.

Обратной стороной этого подхода является то, что вы используете только один Runner для тестового класса. Это затрудняет составление нескольких бегунов. Однако недостатки, создаваемые Runners с JUnit 4, можно преодолеть с помощью следующих параметров:

JUnit 4 использует правила в дополнение к Runners, что предоставляет вам гибкое решение для добавления или переопределения поведения каждого метода тестирования.

Читайте также:  deonica или gillette что лучше

Можно создавать правила для аннотирования полей тестового класса. Однако у Rules есть проблема постоянства. Проще говоря, правила могут выполняться только до и после запуска теста, но не могут быть реализованы внутри теста.

Итак, как среда JUnit 5 решает эту давнюю проблему JUnit 4? JUnit 5 предлагает механизм расширения, который открывает сторонние инструменты или API через модель расширения. Он состоит из единой и последовательной концепции API-интерфейсов расширения для преодоления ограничений конкурирующих точек расширения JUnit 4 (например, Runner, TestRule и MethodRule).

Теперь, когда мы рассмотрели суть расширений JUnit 5, вот ряд вопросов, которые возникают у разработчиков Java:

Почему мы должны использовать расширения?

Сколько усилий требуется для создания расширения JUnit 5?

Модель расширения лучше, чем «Модель программирования»?

Вот что упоминается в основных принципах JUnit 5:

Лучше включить новую функциональность, создав или расширив точку расширения, а не добавляя функциональность как основную.

Архитектура JUnit 5

Предыдущие версии фреймворка JUnit (т.е. до JUnit 4) поставлялись в одном jar файле. Однако JUnit 5 архитектурно отличается от более ранних версий JUnit. Поэтому JUnit 5 поставляется в разных модулях, используя новую архитектуру, которая разделяет API, механизм выполнения, выполнение и интеграцию.

JUnit 5 может использоваться только с версиями Java выше или равными 8. Вот три модуля, которые составляют архитектуру JUnit 5:

Платформа JUnit: предоставляет API для инструментов обнаружения и запуска тестов. Он определяет интерфейс между JUnit и клиентами, которые хотят запускать тесты из IDE, инструментов сборки или консоли.

JUnit Jupiter: предоставляет API на основе аннотаций для написания модульных тестов JUnit 5, а также механизм тестирования, который позволяет их запускать.

JUnit Vintage: предлагает механизм тестирования для запуска тестов JUnit 3 и JUnit 4, тем самым обеспечивая обратную совместимость (с более ранними версиями платформы JUnit).

Модель программирования или Модель расширения

Если вы QA-инженер, который регулярно пишет тесты, вы обязательно будете использовать модель программирования. С другой стороны, модель расширения предоставляет несколько интерфейсов в виде API-интерфейсов расширений, которые могут быть реализованы поставщиками расширений (разработчиками или поставщиками инструментов) для расширения основных функций JUnit 5.

Архитектура JUnit 5

Модель расширения JUnit Jupiter предоставляется через небольшой интерфейс в пакете org.junit.jupiter.api.extension, который может использоваться разработчиками или поставщиками расширений.

Теперь, когда мы рассмотрели основы расширений JUnit 5, давайте напишем код примера, который иллюстрирует расширения JUnit 5. Для этого давайте создадим Java-проект с тремя примерами тестов для Java-класса, используя Eclipse IDE:

Вот пример Java кода, демонстрирующий простое расширение JUnit 5:

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

Как зарегистрировать расширения JUnit 5

Регистрация одного или нескольких расширений в JUnit 5 выполняется через механизм Java ServiceLoader. Существует три способа регистрации расширений: декларативно, программно и автоматически.

Регистрация одного или нескольких расширений может быть выполнена с помощью аннотаций в тестовом интерфейсе, тестовом классе (или его поле) или тестовом методе в зависимости от типа регистрации:

Декларативная регистрация: аннотацию @ExtendWith (classReference.class) следует использовать для применения расширения к полям класса, тестовым интерфейсам, тестовым методам или пользовательским составным аннотациям.

Для демонстрирации расширения JUnit 5, мы использовали пример, который показывает обработку исключений результатов теста:

Мы использовали аннотацию @ExtendWith (AdditionalOutputExtension.class) для регистрации указанного выше класса, чтобы среда JUnit могла использовать его на более позднем этапе.

Программная регистрация: мы можем использовать аннотацию @RegisterExtension, применив ее к полям в тестовых классах:

Автоматическая регистрация: мы можем использовать java.util.ServiceLoader для автоматического обнаружения и регистрации сторонних расширений.

Условное выполнение теста JUnit 5 с аннотациями

Во-первых, условное выполнение теста позволяет запускать (включать) или пропускать (отключать) тестовые сценарии в зависимости от определенных условий использу\ API org.junit.jupiter.api.condition. Давайте посмотрим, как аннотации пакета условий можно использовать для реализации условного выполнения теста в JUnit 5.

1. Условия операционной системы

Условия операционной системы можно использовать с аннотациями @EnabledOnOs и @DisabledOnOs. Условия помогают запустить тест JUnit 5 на конкретной платформе (или операционной системе).

2. Условия среды выполнения Java

Тестовые сценарии можно запускать при определенных условиях, связанных с JRE (Java Runtime Environment), или в определенном диапазоне диапазона версии JRE с использованием аннотаций @EnabledOnJre, @DisabledOnJre и @EnabledForJreRange.

3. Условия собственности системы

Тестовые сценарии могут быть включены или отключены в зависимости от системного свойства с помощью аннотаций @EnabledIfSystemProperty и / или @DisabledIfSystemProperty.

4. Условия переменных окружающей среды

Тестовые сценарии JUnit 5 могут быть включены или отключены в зависимости от состояния (или значения) переменных среды. Это можно сделать с помощью аннотаций @EnabledIfEnvironmentVariable и @DisabledIfEnvironmentVariable в среде JUnit 5.

5. Пользовательские условия

Пользовательские условия могут быть установлены для включения или отключения тестовых сценарии через API расширения ExecutionCondition. Вот два способа реализации тестовых примеров, которые выполняются в определенных (настраиваемых) условиях:

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

Читайте также:  что делать если закрылись все вкладки в браузере яндекс

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

Пользовательские аннотации также могут быть созданы с нуля с помощью API расширения ExecutionCondition. Используя этот подход, вы можете обойтись без использования встроенных аннотаций. Чтобы продемонстрировать пользовательские аннотации с использованием примера расширения JUnit 5, мы запускаем тесты в условиях среды выполнения (т. е. среда может быть для разработки, контроля качества или производственная), как показано ниже:

Здесь условие для запуска теста add() выполняется в тестовой среде или среде разработки (не в реальном времени). Вот как вы можете создать аннотацию @Environment с нуля и реализовать ее в примере расширения JUnit 5:

Мы создаем файл Environment.java и устанавливаем атрибут enabledFor, чтобы добавить в него параметры. Затем созданная аннотация должна зарегистрировать расширение условия через файл EnvironmentExecutionCondition с помощью аннотации @ExtendWith.

Создайте файл EnvironmentExecutionCondition, в котором будут указаны все условия для реализации ExecutionCondition API.

При запуске тестов в среде Dev или QA, тест «add» будет активен и выполнен, тогда как тесты не будут выполняться, если вы находитесь в среде Prod.

Чтобы выполнить тесты в данной среде, запустите соответствующую команду для аргументов виртуальной машины в параметре «run configurations»:

Как создать расширения JUnit 5 путем реализации TestInstanceFactory

Мы можем создавать расширения JUnit 5, реализуя API TestInstanceFactory для создания экземпляров тестовых классов. Они должны выполняться перед выполнением каждого метода тестирования.

Затем созданный тестовый экземпляр можно получить из инфраструктуры внедрения зависимостей или путем вызова статического фабричного метода для его создания.

Следующий пример расширения JUnit 5 демонстрирует использование фабрик тестовых экземпляров во внешних и внутренних классах:

Как протестировать обратные вызовы жизненного цикла в JUnit 5

Методы жизненного цикла и жизненный цикл тестового экземпляра

В жизненном цикле основного тестового экземпляра JUnit 5 определяет жизненный цикл класса и метода, управляемый следующими аннотациями:

Методы, помеченные @BefсегоoreAll и @AfterAll, должны выполняться до и после всех тестовых методов в классе. С другой стороны, методы, аннотированные @BeforeEach и @AfterEach, должны выполняться соответственно до и после каждого метода тестирования.

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

Выполнение этого кода дает следующий результат:

Жизненный цикл каждого метода

Поведение жизненного цикла теста можно изменить с помощью API org.junit.jupiter.api.TestInstance, который позволяет изменить жизненный цикл по умолчанию (для тестового класса или метода тестирования). Это можно сделать, добавив в тестовый класс аннотацию @TestInstance (TestInstance.Lifecycle.PER_CLASS).

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

По результату выполнения теста измененное поведение следующее:

Жизненный цикл для каждого класса

Жизненный цикл расширения JUnit 5

Помимо жизненного цикла для каждого класса и для каждого метода, JUnit 5 Jupiter предлагает различные интерфейсы, которые определяют API-интерфейсы для расширения тестов в различных точках жизненного цикла выполнения. Поэтому JUnit 5 вызывает обратные вызовы расширений для реализации требуемого поведения.

API-интерфейсы являются частью пакета org.junit.jupiter.api.extension. Вот API, определяющие жизненный цикл расширения:

Мы можем создать расширение для тестового класса, реализовав интерфейсы BeforeAllCallback, AfterAllCallback, BeforeEachCallback и AfterEachCallback.

Вот как применить указанную точку расширения к тест-классу:

Вот результат выполнения:

Постобработка тестового экземпляра в JUnit 5

Модель расширений Juniper обеспечивает возможность постобработки тестовых экземпляров после создания тестовых экземпляров путем реализации интерфейса TestInstancePostProcessor. В соответствии с фабрикой тестового экземпляра он может вызывать метод инициализации в тестовом экземпляре, используя, например, зависимости внедрения в экземпляр для использования постобработки тестового экземпляра.

Чтобы проиллюстрировать это, мы возьмем пример системы журналирования из API-интерфейса log4j, который выполняет и записывает журналы после каждого выполнения теста. Давайте рассмотрим пример исключения JUnit 5:

Обратный вызов перед уничтожением тестового экземпляра в JUnit 5

Модель расширений также определяет API для расширений, которые необходимо обработать между тестовыми экземплярами и их окончательным уничтожением. Например, обратный вызов перед уничтожением тестового экземпляра обычно используется в таких случаях, как очистка внедренных зависимостей после их использования в тестовом экземпляре.

Разрешение параметра в JUnit 5

Большинство методов тестирования не имеют параметров. Мы используем интерфейс ParameterResolver при использовании параметров, который определяет API org.junit.jupiter.api.extension.ParameterResolver для расширений. Он предоставляет функциональные возможности для динамического разрешения параметров во время выполнения.

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

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

Эти параметры должны быть разрешены во время выполнения экземпляром типа ParameterResolver, который необходимо зарегистрировать ранее.

По умолчанию JUnit 5 автоматически регистрирует ParameterResolver, используя три встроенных преобразователя:

Читайте также:  при какой температуре пекут хлеб дома

TestInfoParameterResolver: используется для разрешения, внедрения экземпляра типа TestInfo и получения информации о тесте, который выполняется.

RepetitionInfoParameterResolver: используется для внедрения экземпляра типа RepetitionInfo только для повторных тестов.

TestReporterParameterResolver: используется для внедрения экземпляра типа TestReporter, позволяя ему добавлять полезную информацию в отчет о тестировании.

Если вы используете JUnit 4, вы можете ознакомиться с блогом, в котором подробно рассказывается о параметризации в JUnit для Selenium Automation.

Обработка исключений в JUnit 5

Интерфейс TestExecutionExceptionHandler определяет API, реализующий расширения, позволяющие полностью настроить поведение тестового примера при возникновении исключения.

В продолжение предыдущего примера расширения JUnit 5 мы использовали ArithmeticException для создания тестового класса в тестовом сценарии для divide, как показано ниже:

Он расширен до класса обработчика исключений для обработки исключения, вызванного операцией деления (при обработке деления на ноль):

Можно использовать традиционный метод создания исключения (с помощью try… catch, Rules и т. д.) или через аннотации, реализовав интерфейс TestExecutionExceptionHandler.

Сторонние расширения фреймворка в JUnit 5

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

Spring TestContext: SpringExtension for Jupiter

1. MockitoExtension

Вот основные способы использования MockitoExtension:

Использование расширений JUnit 5, доступных в артефакте mockito-junit-jupiter (наиболее предпочтительный вариант)

Использование расширения Mockito можно увидеть в действии, используя расширение и добавив @ExtendWith в тестовый класс и аннотируя моделируемые поля с помощью @Mock.

Например, если нам нужно протестировать класс SERVICE и имитировать базу данных, нам нужно использовать следующий код:

Тестовый класс будет выглядеть так:

2. Selenium-Jupiter

Объединив силу Selenium, самой популярной среды тестирования веб-браузеров, и мощность JUnit 5, selenium-jupiter позволяет создавать тесты Selenium с использованием локальных и/или удаленных браузеров. Благодаря этому вы можете запускать различные типы тестов для проверки функциональности веб-приложений и мобильных приложений. Кроме того, расширение selenium-jupiter может использоваться для автоматизации Selenium тестирования.

Для проектов Maven следует использовать следующую зависимость:

Selenium-Jupiter можно использовать, просто используя аннотацию @ExtendWith в интерфейсе SeleniumJupiter для выполнения тестирования кроссбраузерной совместимости. Вот демонстрационный пример:

Как использовать Selenium-Jupiter для автоматизации Selenium тестирования

Selenium-Jupiter поддерживает тестирование удаленных веб-браузеров в Selenium Grid с помощью комбинации DriverCapabilities и RemoteWebDriver. Вы также можете выполнить параллельное тестирование в Selenium, запустив тесты в различных комбинациях браузера и платформы с помощью LambdaTest.

Как использовать Selenium-Jupiter для тестирования мобильных устройств

Чтобы создать экземпляр ApiumDriver для управления мобильными устройствами, аннотация DriverCapabilities. Selenium-Jupiter автоматически запустит экземпляр сервера Appium.

Как использовать Selenium-Jupiter для выполнения автоматизации Selenium тестирования в Cloud Grid

Selenium-Jupiter позволяет запускать автоматизации Selenium тестов на облачной платформе кроссбраузерного тестирования, такой как LambdaTest. Основными преимуществами облачного тестирования являются улучшенное покрытие браузера, устранение связанных с окружающей средой задержек в расписании, повышение качества продукта и снижение совокупной стоимости владения (TCO). Ознакомьтесь с нашим руководством по облачному тестированию, в котором описаны многочисленные преимущества переноса тестов в облачную среду Selenium Grid, такую ​​как LambdaTest.

После создания учетной записи на LamdaTest обратите внимание на имя пользователя и доступ из раздела профиля LambdaTest. Эти учетные данные необходимы для доступа к облачной сетке. Затем вы можете сгенерировать желаемые возможности с помощью LambdaTest Capabilities Generator.

Ниже показан пример запуска теста JUnit 5 в LambdaTest Grid:

Вот снимок во время выполнения, который указывает, что выполнение теста было успешным.

3. Spring TestContext: SpringExtension для Jupiter

Spring TestContext, представленный в Spring 5, представляет собой среду Spring, которая предлагает полную интеграцию с моделью программирования JUnit 5 Jupiter. Его можно найти в пакете org.springframework.test.context.junit.jupiter.SpringExtension.

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

Ниже показан пример расширения JUnit 5, демонстрирующий использование Spring TestContext:

Заключение и рекомендации

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

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

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

Мы также можем более подробно проработать те, которые не кажутся вам понятными в этом руководстве. Нам также интересны ваши отзывы об использовании точек расширения JUnit Jupiter в ваших проектах. Исходный код приведенных выше примеров можно найти на GitHub.

Источник

Сказочный портал