1. Введение

Тестирование – это процесс проверки функционала программы с целью подтверждения того, что она работает в соответствии с определёнными требованиями. Unit-тестирование – это тестирование с помощью тестов, которые пишутся, непосредственно, на уровне разработчика (тестирование определённой сущности – метод или класс). Это крайне важный этап разработки ПО, который помогает создавать качественный продукт.

Unit-тестирование делится на две большие группы:

  • Ручное тестирование

  • Автоматизированное тестирование

Ручное тестирование Автоматизированное тестирование

Ручное выполнение тестов без помощи каких-либо средств.

Использование специальных средств для автоматизированного тестирования

Не программируется
Нет возможности для написания сложных тестов для тестирования сложных моделей поведения.

Программируется
Тестировщики могут написать сложные тесты для тестирования сложных моделей программирования

Низкая надёжность
Ручное тестирование имеет низкую надёжность, так как крайне подвержено влиянию человеческого фактора.

Высокая надёжность
Автоматизированное тестирование точное и надёжное.

Большие затраты времени
Связано с тем, что человек имеет крайне ограниченные возможность в скорости работы.

Быстро
Автоматизированные тесты выполняются на порядок быстрее, чем это может сделать человек.

2. JUnit

JUnit – это фреймворк, разработанный для тестирования программ, написанных с использованием технологии Java. Он лежит в основе TDD (Test-Driven Development) и входит в семейство фреймворков для тестирования xUnit.

Главная идея Test-Driven Developmentсначала тесты, потом код. Это означает, что сначала определяется, что должно получиться в результате работы того или иного куска кода и пишем тесты. Тесты проверяют идентичность результата с требуемым, после чего пишем сам кусок кода, который и будет тестироваться. Данный подход увеличивает эффективность работы разработчика и позволяет писать более стабильный код. В результате этого получается меньшее количество времени, которое затрачивается на отладку программы.

2.1. Свойства JUnit

  • Фреймворк с открытым исходным кодом, который используется для написания и выполнения тестов.

  • Позволяет писать код более быстро и качественно.

  • Крайне прост в использовании.

  • Поддерживает аннотации для идентификации методов.

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

  • Тесты могут быть организованы в test suites (связки тестов).

  • Имеет визуальную индикацию состояния тестов (красные – не пройдены, зелёные – пройдены).

3. Тестовый случай

Test Case (Тестовый случай) в unit-тестировании – это часть кода, которая проверяет, что другая часть кода, например метод, работает в соответствии с определёнными требованиями.

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

Необходимо создавать, как минимум, два test cases для каждого требования – положительный и отрицательный. Если требование имеет под-требования, каждое из них должно тестироваться отдельно.

4. JUnit 5

JUnit 5 требует Java 8 (или выше) для запуска. Однако все равно можно протестировать код, скомпилированный с предыдущими версиями JDK.

В отличие от предыдущих версий JUnit, JUnit 5 состоит из нескольких разных модулей из трех разных подпроектов.

JUnit 5 = Platform JUnit + JUnit Jupiter + JUnit Vintage

  • Platform JUnit
    Служит основой для запуска тестирования на JVM. Он также определяет Test Engine API для разработки инфраструктуры тестирования, работающей на платформе. Кроме того, платформа предоставляет инструменты для запуска тестов с помощью CLI и инструменты для запуска на основе JUnit 4 для запуска любого Test Engine. Первоклассная поддержка Platform JUnit также существует в популярных IDE (см. IntelliJ IDEA, Eclipse, NetBeans и Visual Studio Code) и инструментах сборки (см. Gradle, Maven и Ant).

  • JUnit Jupiter
    Является сочетанием новой модели программирования и модели расширения для написания тестов и расширений в JUnit 5. JUnit Jupiter обеспечивает Test Engine для выполнения тестов на основе Jupiter на Platform JUnit.

  • JUnit Vintage
    Обеспечивает Test Engine запуск тестов на основе JUnit 3 и JUnit 4 на Platform JUnit.

4.1. Аннотации

JUnit Jupiter поддерживает следующие аннотации для настройки тестов и расширения фреймворка.

Аннотация Свойство

@Test

Означает, что метод является методом тестирования. В отличие от аннотации JUnit 4, эта аннотация не объявляет никаких атрибутов, так как тестовые расширения в JUnit Jupiter работают на основе собственных специальных аннотаций. Такие методы наследуются, если они не переопределены.

@ParameterizedTest

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

@RepeatedTest

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

@TestFactory (JUnit5)

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

@TestTemplate

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

@TestMethodOrder

Используется для настройки порядка выполнения тестового метода для аннотированного тестового класса; похож на JUnit 4’s. Такие аннотации наследуются.

@TestInstance

Используется для настройки жизненного цикла экземпляра теста для аннотированного тестового класса. Такие аннотации наследуются.

@DisplayName (JUnit5)

Объявляет пользовательское имя дисплея для тестового класса или метода тестирования. Такие аннотации не наследуются.

@DisplayNameGeneration

Объявляет пользовательский генератор имен отображения для тестового класса. Такие аннотации наследуются.

@BeforeEach (JUnit5)

Означает, что аннотированный метод должен быть выполнен перед каждым, или методом в текущем классе; по аналогии с JUnit 4’s. Такие методы наследуются, если они не переопределены.

@AfterEach (JUnit5)

Означает, что аннотированный метод должен быть выполнен после каждого, или метода в текущем классе; по аналогии с JUnit 4’s. Такие методы наследуются, если они не переопределены.

@BeforeAll (JUnit5)

Означает, что аннотированный метод должен быть выполнен прежде всего, и методы в текущем классе; по аналогии с JUnit 4’s. Такие методы наследуются (если они не скрыты или переопределены)и должны быть (если не используется жизненный цикл "в каждом классе" экземпляра теста).

@AfterAll (JUnit5)

Означает, что аннотированный метод должен быть выполнен в конце концов, и методы в текущем классе; по аналогии с JUnit 4’s. Такие методы наследуются (если они не скрыты или переопределены)и должны быть (если не используется жизненный цикл "в каждом классе" экземпляра теста).

@Nested (JUnit5)

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

@Tag (JUnit5)

Используется для объявления тегов для фильтрации тестов, либо на уровне класса или метода; аналогично тестовым группам в TestNG или Categories в JUnit 4. Такие аннотации наследуются на уровне класса, но не на уровне метода.

@Disabled (JUnit5)

Используется для отключения тестового класса или метода тестирования; по аналогии с JUnit 4’s. Такие аннотации не наследуются.@Ignore

@Timeout

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

@ExtendWith (JUnit5)

Используется для регистрации расширений декларативно. Такие аннотации наследуются.

@RegisterExtension

Используется для регистрации расширений программно через поля. Такие поля наследуются, если они не затенены.

@TempDir

Используется для поставки временного каталога с помощью инъекций поля или инъекций параметра в метод жизненного цикла или метод тестирования; расположен в пакете org.junit.jupiter.api.io

Все основные аннотации находятся в org.junit.jupiter.api пакете в junit-jupiter-api модуле.

4.2. Assertions

JUnit 5 поставляется со многими стандартными Assertions (утверждениями), т.е. методами, которые проверяют результат работы кода на соответствие ожидаемому результату. Их можно найти в классе org.junit.jupiter.api.Assertions

Основные assertions:

  • assertEquals(),

  • assertArrayEquals(),

  • assertSame(),

  • assertNotSame(),

  • assertTrue(),

  • assertFalse(),

  • assertNull(),

  • assertNotNull(),

  • assertLinesMatch(),

  • assertIterablesMatch()