Рубрики
Без рубрики

Учебник Junit 5 для начинающих

Этот пост был первоначально опубликован в programmingtechie.com Блок 5 является одним из популярных тестовых модулей… С пометкой java, junit 5, новички, программирование.

Этот пост был первоначально опубликован в Этот пост был первоначально опубликован в

Junit 5 является одной из популярных платформ тестирования в мире разработки Java и поддерживает новейшие функции Java 8.

Если вы, как и я, изучаете визуальное, ознакомьтесь с приведенным ниже видеоуроком:

содержание

  • Архитектура Junit 5
    • Платформа Junit
    • Юнит Юпитер
    • Винтажный Джунит
  • Исходный код для тестируемого проекта
    • Исходный код для начального проекта
  • Написание нашего первого теста
  • Тестирование исключений с помощью бросков утверждения()
  • Понимание жизненного цикла тестирования
    • Реализация аннотаций жизненного цикла в нашем тесте
    • @До всего и @после всего
    • @До каждого и @после каждого
    • Жизненный цикл тестового экземпляра по умолчанию
    • Изменение жизненного цикла экземпляра Теста по умолчанию
  • Условные казни
  • Допущения
  • Повторные Испытания
  • Параметризованные тесты
    • Источник ценности
    • Источник метода
    • CSV-источник
    • Источник Csv-Файла
  • Отключенные тесты
  • Вложенные тесты
  • Запуск тестов с использованием плагина Maven Surefire
  • Вывод

Несмотря на то, что JUnit 5 является преемником Junit 4, архитектура фреймворка совершенно иная, поэтому давайте взглянем на архитектуру Junit 5.

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

Архитектуру Junit 5 можно разделить на 3 различных проекта:

  • Платформа Junit
  • Юнит Юпитер
  • Винтажный Джунит

Платформа Junit

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

Юнит Юпитер

Этот проект предоставляет API для написания ваших тестов и расширений Junit, он содержит новые аннотации и реализацию Test Engine для запуска этих тестов на платформе.

Винтажный Джунит

Этот проект предоставляет реализацию Test Engine для поддержки обратной совместимости тестов, написанных с помощью Junit 3 и Junit4.

Вы можете ознакомиться со схемой архитектуры ниже:

Мы собираемся использовать приложение Contact Manager, изучая, как писать тесты с помощью Junit 5.

Вы можете скачать исходный код приложения по приведенной ниже ссылке на Github: https://github.com/SaiUpadhyayula/contact-manager

Исходный код для начального проекта

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

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

Приложение использует Maven для управления зависимостями и построения проекта. Если вы хотите изучить Maven, вы можете ознакомиться с моим Полным учебным пособием по Maven сообщением в блоге. Приложение в основном содержит 2 класса, Приложение в основном содержит 2 класса, и

и

public class Contact {
    private String firstName;
    private String lastName;
    private String phoneNumber;

    public Contact(String firstName, String lastName, String phoneNumber) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.phoneNumber = phoneNumber;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public void validateFirstName() {
        if (this.firstName == null)
            throw new RuntimeException("First Name Cannot be null");
    }

    public void validateLastName() {
        if (this.lastName == null)
            throw new RuntimeException("Last Name Cannot be null");
    }

    public void validatePhoneNumber() {
        if (this.phoneNumber.length() != 10) {
            throw new RuntimeException("Phone Number Should be 10 Digits Long");
        }
        if (!this.phoneNumber.matches("\\d+")) {
            throw new RuntimeException("Phone Number Contain only digits");
        }
        if (!this.phoneNumber.startsWith("0")) {
            throw new RuntimeException("Phone Number Should Start with 0");
        }
    }
}

Этот класс содержит всего 3 необходимых поля: Имя, Фамилию и Номер телефона.

Этот класс содержит всего 3 необходимых поля: Имя, Фамилию и Номер телефона.

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ContactManager {

    Map contactList = new ConcurrentHashMap();

    public void addContact(String firstName, String lastName, String phoneNumber) {
        Contact contact = new Contact(firstName, lastName, phoneNumber);
        validateContact(contact);
        checkIfContactAlreadyExist(contact);
        contactList.put(generateKey(contact), contact);
    }

    public Collection getAllContacts() {
        return contactList.values();
    }

    private void checkIfContactAlreadyExist(Contact contact) {
        if (contactList.containsKey(generateKey(contact)))
            throw new RuntimeException("Contact Already Exists");
    }

    private void validateContact(Contact contact) {
        contact.validateFirstName();
        contact.validateLastName();
        contact.validatePhoneNumber();
    }

    private String generateKey(Contact contact) {
        return String.format("%s-%s", contact.getFirstName(), contact.getLastName());
    }
}

Этот класс содержит основную бизнес-логику для хранения контактной информации.

Теперь пришло время написать наш первый тест 5-го блока.

Я собираюсь создать тестовый класс под названием ContactManagerTest.java в папке src/test/java .

Я собираюсь создать тестовый класс под названием || ContactManagerTest.java || в папке || src/test/java ||.

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

public class ContactManagerTest {

    @Test
    @DisplayName("Should Create Contact")
    public void shouldCreateContact() {
        ContactManager contactManager = new ContactManager();
        contactManager.addContact("John", "Doe", "0123456789");
        assertFalse(contactManager.getAllContacts().isEmpty());
        assertEquals(1, contactManager.getAllContacts().size());
    }
}
  • Мы создали метод под названием should Create Contact() , который является тестированием метода, созданием контакта. Junit понимает, что этот метод является тестом, посмотрев на аннотацию @Test .
  • Взглянув на имя метода должен создать контакт() мы понимаем, что пытается сделать метод, но мы также можем предоставить пользовательское имя для этого метода, используя аннотацию @DisplayName .
  • Внутри метода мы создали контакт, указав имя, фамилию и номер телефона в методе addContact() класса ContactManager .
  • Мы можем получить всю контактную информацию с помощью метода getAllContacts() .
  • В качестве последнего шага мы проверяем, что результат getAllContacts() не пуст, а размер списка getAllContacts() равен ровно 1.

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

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

У нас есть класс Assertions, который предоставляет ряд статических методов, которые мы можем использовать в наших тестах.

Если вы выполните описанный выше тест в IntelliJ, тест будет зеленым. Поздравляю, вы написали свой первый тест 5-го блока.

Более подробную информацию об этом классе вы можете найти в документации – https://junit.org/junit5/docs/5.0.1/api/org/junit/jupiter/api/Assertions.html

В нашем первом тестовом примере мы успешно протестировали Счастливый путь.

Теперь давайте рассмотрим некоторые другие сценарии.

Вот некоторые проверки, которые выполняются при создании контакта:

  • Имя не должно быть нулевым
  • Фамилия не должна быть нулевой
  • Номер Телефона Должен:
  • Быть Длиной Ровно 10 Цифр
  • Содержать только цифры
  • Начните с 0

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

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

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;

public class ContactManagerTest {

    @Test
    @DisplayName("Should Create Contact")
    public void shouldCreateContact() {
        ContactManager contactManager = new ContactManager();
        contactManager.addContact("John", "Doe", "0123456789");
        assertFalse(contactManager.getAllContacts().isEmpty());
        assertEquals(1, contactManager.getAllContacts().size());
    }

    @Test
    @DisplayName("Should Not Create Contact When First Name is Null")
    public void shouldThrowRuntimeExceptionWhenFirstNameIsNull() {
        ContactManager contactManager = new ContactManager();
        Assertions.assertThrows(RuntimeException.class, () -> {
            contactManager.addContact(null, "Doe", "0123456789");
        });
    }
}

  • 2-й тестовый пример проверяет, не удалось ли создать контакт, когда мы вводим Имя как Нулевое.
  • Мы утверждаем, что метод addContact() выдает Исключение времени выполнения
  • Мы можем утверждать исключения, используя метод assert throws() из класса Assertions
  • Метод assert throws() принимает тип исключения в качестве первого параметра, а исполняемый файл, который генерирует исключение, – в качестве второго параметра.

Мы можем написать аналогичные тестовые примеры также для полей Фамилия и Номер телефона, как показано ниже:

Мы можем написать аналогичные тестовые примеры также для полей Фамилия и Номер телефона, как показано ниже:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;

public class ContactManagerTest {

    @Test
    @DisplayName("Should Create Contact")
    public void shouldCreateContact() {
        ContactManager contactManager = new ContactManager();
        contactManager.addContact("John", "Doe", "0123456789");
        assertFalse(contactManager.getAllContacts().isEmpty());
        assertEquals(1, contactManager.getAllContacts().size());
    }

    @Test
    @DisplayName("Should Not Create Contact When First Name is Null")
    public void shouldThrowRuntimeExceptionWhenFirstNameIsNull() {
        ContactManager contactManager = new ContactManager();
        Assertions.assertThrows(RuntimeException.class, () -> {
            contactManager.addContact(null, "Doe", "0123456789");
        });
    }

    @Test
    @DisplayName("Should Not Create Contact When Last Name is Null")
    public void shouldThrowRuntimeExceptionWhenLastNameIsNull() {
        ContactManager contactManager = new ContactManager();
        Assertions.assertThrows(RuntimeException.class, () -> {
            contactManager.addContact("John", null, "0123456789");
        });
    }

    @Test
    @DisplayName("Should Not Create Contact When Phone Number is Null")
    public void shouldThrowRuntimeExceptionWhenPhoneNumberIsNull() {
        ContactManager contactManager = new ContactManager();
        Assertions.assertThrows(RuntimeException.class, () -> {
            contactManager.addContact("John", "Doe", null);
        });
    }
}

Вы можете заметить, что я добавил аналогичные тестовые примеры и для полей Номер телефона и Фамилия.

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

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

  • @Перед всеми

Метод, отмеченный этой аннотацией, будет выполнен до того, как любой из методов @Test будет выполнен внутри тестового класса.

  • @Перед каждым

Метод, отмеченный этой аннотацией, будет выполняться перед каждым @Test методом в тестовом классе.

  • @После каждого

Метод, отмеченный этой аннотацией, будет выполняться после каждого @Test метода в тестовом классе.

  • @В конце концов

Метод, отмеченный этой аннотацией, будет выполнен после выполнения всех методов @Test в классе Test.

Методы Before ( @beforeAll , @beforeEach ) выполняют некоторые действия инициализации, такие как настройка тестовых данных или данных среды, перед выполнением тестов.

Методы после ( @После l, @afterEach ) выполните действия по очистке, такие как очистка данных созданной среды или тестовых данных.

@Перед всеми и @AfterAll вызываются только один раз для всего теста, и методы обычно помечаются как статические .

Реализация аннотаций жизненного цикла в нашем тесте

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

В наших 4 тестах мы можем заметить, что мы создаем экземпляр Менеджер контактов в начале каждого теста.

Эта логика может входить в метод, который помечен либо @beforeAll , либо @beforeEach

@До всего и @после всего

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;

public class ContactManagerTest {

    private static ContactManager contactManager;

    @BeforeAll
    public static void setup() {
        System.out.println("Instantiating Contact Manager before the Test Execution");
        contactManager = new ContactManager();
    }

    @Test
    @DisplayName("Should Create Contact")
    public void shouldCreateContact() {
        contactManager.addContact("John", "Doe", "0123456789");
        assertFalse(contactManager.getAllContacts().isEmpty());
        assertEquals(1, contactManager.getAllContacts().size());
    }

    @Test
    @DisplayName("Should Not Create Contact When First Name is Null")
    public void shouldThrowRuntimeExceptionWhenFirstNameIsNull() {
        ContactManager contactManager = new ContactManager();
        Assertions.assertThrows(RuntimeException.class, () -> {
            contactManager.addContact(null, "Doe", "0123456789");
        });
    }

    @Test
    @DisplayName("Should Not Create Contact When Last Name is Null")
    public void shouldThrowRuntimeExceptionWhenLastNameIsNull() {
        ContactManager contactManager = new ContactManager();
        Assertions.assertThrows(RuntimeException.class, () -> {
            contactManager.addContact("John", null, "0123456789");
        });
    }

    @Test
    @DisplayName("Should Not Create Contact When Phone Number is Null")
    public void shouldThrowRuntimeExceptionWhenPhoneNumberIsNull() {
        ContactManager contactManager = new ContactManager();
        Assertions.assertThrows(RuntimeException.class, () -> {
            contactManager.addContact("John", "Doe", null);
        });
    }
}

Я создал метод, называемый setup() , который помечен аннотацией @beforeAll , внутри этого метода я создал экземпляр ContactManager и назначил объект переменной static .

Я также добавил метод, называемый tearDown() , который помечен аннотацией @afteRall , мы ожидаем, что этот метод будет выполнен в конце теста.

Если вы снова запустите тесты, вы должны увидеть результат, как показано на рисунке ниже:

@До каждого и @после каждого

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

Обратите внимание, что Junit всегда создает новый экземпляр теста перед выполнением каждого @Тест метод.

import org.junit.jupiter.api.*;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;

public class ContactManagerTest {

    private ContactManager contactManager;

    @BeforeAll
    public static void setupAll() {
        System.out.println("Should Print Before All Tests");
    }

    @BeforeEach
    public void setup() {
        System.out.println("Instantiating Contact Manager");
        contactManager = new ContactManager();
    }

    @Test
    @DisplayName("Should Create Contact")
    public void shouldCreateContact() {
        contactManager.addContact("John", "Doe", "0123456789");
        assertFalse(contactManager.getAllContacts().isEmpty());
        assertEquals(1, contactManager.getAllContacts().size());
    }

    @Test
    @DisplayName("Should Not Create Contact When First Name is Null")
    public void shouldThrowRuntimeExceptionWhenFirstNameIsNull() {
        Assertions.assertThrows(RuntimeException.class, () -> {
            contactManager.addContact(null, "Doe", "0123456789");
        });
    }

    @Test
    @DisplayName("Should Not Create Contact When Last Name is Null")
    public void shouldThrowRuntimeExceptionWhenLastNameIsNull() {
        Assertions.assertThrows(RuntimeException.class, () -> {
            contactManager.addContact("John", null, "0123456789");
        });
    }

    @Test
    @DisplayName("Should Not Create Contact When Phone Number is Null")
    public void shouldThrowRuntimeExceptionWhenPhoneNumberIsNull() {
        Assertions.assertThrows(RuntimeException.class, () -> {
            contactManager.addContact("John", "Doe", null);
        });
    }

    @AfterEach
    public void tearDown() {
        System.out.println("Should Execute After Each Test");
    }

    @AfterAll
    public static void tearDownAll() {
        System.out.println("Should be executed at the end of the Test");
    }
}

Я переместил логику для создания объекта Менеджер контактов внутри метода setup() , помеченного @beforeEach и я переименовал метод, помеченный @beforeAll , в настроить все()

Я также представил новый метод, называемый tearDown() , который просто регистрирует некоторый случайный текст, просто чтобы показать вам, что метод выполняется после каждого выполнения теста.

Если вы выполните описанный выше тест, то вот как должен выглядеть результат:

Жизненный цикл тестового экземпляра по умолчанию

Как упоминалось выше, Junit создает экземпляр класса Test для каждого метода, помеченного @Test .

По этой причине метод, отмеченный знаком @beforeAll и @AfterAll должны быть помечены статическим .

Изменение жизненного цикла экземпляра Теста по умолчанию

Вы можете изменить это поведение по умолчанию, проинструктировав Junit создать экземпляр тестового класса только один раз, используя приведенную ниже аннотацию.

@testInstance(Жизненный цикл. ЗА_КЛАСС)

Используя приведенную выше аннотацию, нет необходимости отмечать @перед всеми и @AfterAll методы как статические .

Мы можем выполнить методы @Test в нашем классе на основе определенного условия, например: представьте, что вы разработали определенную функциональность в Linux для нашего приложения Contact Manager. После сохранения контакта мы выполняем некоторую дополнительную логику, специфичную для операционной системы Linux.

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

Вы можете включить это условное выполнение, используя различные аннотации:

  • @@Включено Нет
  • @@Отключен

Эти аннотации принимают значения для обычных операционных систем, таких как MAC , LINUX , ОКНА .

Вы можете увидеть пример использования этой аннотации ниже:

@Test
@DisplayName("Should Create Contact")
@EnabledOnOs(value = OS.MAC, disabledReason = "Should Run only on MAC")
public void shouldCreateContact() {
    contactManager.addContact("John", "Doe", "0123456789");
    assertFalse(contactManager.getAllContacts().isEmpty());
    assertEquals(1, contactManager.getAllContacts().size());
}

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

Мы также можем выполнять условные утверждения, используя Junit 5 Предположения .

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

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

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

Вы можете выполнить эти предположения в Junit 5 аналогично утверждениям.

@Test
@DisplayName("Test Contact Creation on Developer Machine")
public void shouldTestContactCreationOnDEV() {
    Assumptions.assumeTrue("DEV".equals(System.getProperty("ENV")));
    contactManager.addContact("John", "Doe", "0123456789");
    assertFalse(contactManager.getAllContacts().isEmpty());
    assertEquals(1, contactManager.getAllContacts().size());
}
  • В приведенном выше тесте вы можете видеть, что мы используем метод Assumptions.assume True() для выполнения тестов, только когда системное свойство ENV равно DEV.
  • Если вышеприведенное предположение не подтвердилось, то тест не будет выполнен.

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

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

Как только вы запустите тест после активации этого свойства, вы увидите, что тест выполнен успешно.

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

Junit 5 предоставляет нам аннотацию @RepeatedTest для выполнения этого требования.

Вы можете повторить тест N раз, передав число в качестве аргумента аннотации. Например: @RepeatedTest(5) запустит тест, отмеченный этой аннотацией, 5 раз.

@DisplayName("Repeat Contact Creation Test 5 Times")
@RepeatedTest(5)
public void shouldTestContactCreationRepeatedly() {
    contactManager.addContact("John", "Doe", "0123456789");
    assertFalse(contactManager.getAllContacts().isEmpty());
    assertEquals(1, contactManager.getAllContacts().size());
}

Если вы выполните описанный выше тест, вы сможете увидеть приведенные ниже результаты:

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

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

Например: @RepeatedTest(значение, )

@DisplayName("Repeat Contact Creation Test 5 Times")
@RepeatedTest(value = 5,
        name = "Repeating Contact Creation Test {currentRepetition} of {totalRepetitions}")
public void shouldTestContactCreationRepeatedly() {
    contactManager.addContact("John", "Doe", "0123456789");
    assertFalse(contactManager.getAllContacts().isEmpty());
    assertEquals(1, contactManager.getAllContacts().size());
}

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

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

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

@Test
@DisplayName("Phone Number should start with 0")
public void shouldTestPhoneNumberFormat() {
    contactManager.addContact("John", "Doe", "0123456789");
    assertFalse(contactManager.getAllContacts().isEmpty());
    assertEquals(1, contactManager.getAllContacts().size());
}

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

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

Вы можете предоставить входные данные для теста различными способами:

Источник ценности

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

Например: @ValueSource(строки = {"строка1","строка2","строка3"})

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

@DisplayName("Phone Number should match the required Format")
@ParameterizedTest
@ValueSource(strings = {"0123456789", "1234567890", "+0123456789"})
public void shouldTestPhoneNumberFormat(String phoneNumber) {
    contactManager.addContact("John", "Doe", phoneNumber);
    assertFalse(contactManager.getAllContacts().isEmpty());
    assertEquals(1, contactManager.getAllContacts().size());
}

В приведенном выше примере мы предоставляем строку номера телефона в разных форматах.

Если вы выполните описанный выше тест, он выдаст следующий результат

Тест проверяет, начинается ли номер телефона с 0 или нет, поскольку мы предоставили неверные входные данные для 2-го и 3-го случаев, тесты не прошли.

Источник метода

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

@DisplayName("Method Source Case - Phone Number should match the required Format")
@ParameterizedTest
@MethodSource("phoneNumberList")
public void shouldTestPhoneNumberFormatUsingMethodSource(String phoneNumber) {
    contactManager.addContact("John", "Doe", phoneNumber);
    assertFalse(contactManager.getAllContacts().isEmpty());
    assertEquals(1, contactManager.getAllContacts().size());
}

private List phoneNumberList() {
    return Arrays.asList("0123456789", "1234567890", "+0123456789");
}

В приведенном выше тесте мы объявили метод, называемый как Список телефонных номеров () который возвращает требуемые входные значения в виде списка<Строка> .

Мы передали имя этого метода в качестве значения аннотации @MethodSource .

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

CSV-источник

Вы можете создать встроенный CSV-файл, содержащий входные данные для теста, и ссылаться на него, используя аннотацию @CsvSource .

Пример: @CsvSource({"1,0123456789", "2,1234567890","3,+0123456789"})

@DisplayName("CSV Source Case - Phone Number should match the required Format")
@ParameterizedTest
@CsvSource({"0123456789", "1234567890","+0123456789"})
public void shouldTestPhoneNumberFormatUsingCSVSource(String phoneNumber) {
    contactManager.addContact("John", "Doe", phoneNumber);
    assertFalse(contactManager.getAllContacts().isEmpty());
    assertEquals(1, contactManager.getAllContacts().size());
}

Источник Csv-Файла

Вы также можете ссылаться на CSV-файл с помощью аннотации @CsvFileSource .

Например: @CsvFileSource(ресурсы)

@DisplayName("CSV File Source Case - Phone Number should match the required Format")
@ParameterizedTest
@CsvFileSource(resources = "/data.csv")
public void shouldTestPhoneNumberFormatUsingCSVFileSource(String phoneNumber) {
    contactManager.addContact("John", "Doe", phoneNumber);
    assertFalse(contactManager.getAllContacts().isEmpty());
    assertEquals(1, contactManager.getAllContacts().size());
}

Содержимое csv-файла выглядит следующим образом:

0123456789
1234567890
+0123456789

Вот как выглядит ожидаемый результат:

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

@Test
@DisplayName("Test Should Be Disabled")
@Disabled
public void shouldBeDisabled() {
    throw new RuntimeException("Test Should Not be executed");
}

Если вы запустите вышеуказанный тест, вы увидите вывод из Junit 5 о том, что тест должен быть отключен() является @Отключен

К настоящему времени вы, возможно, заметили, что наш тест Менеджер контактов содержит множество методов тестирования, мы можем организовать эти тесты во вложенные тесты, используя аннотацию @Nested .

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

@Nested
class ParameterizedTests {
    @DisplayName("Phone Number should match the required Format")
    @ParameterizedTest
    @ValueSource(strings = {"0123456789", "1234567890", "+0123456789"})
    public void shouldTestPhoneNumberFormatUsingValueSource(String phoneNumber) {
        contactManager.addContact("John", "Doe", phoneNumber);
        assertFalse(contactManager.getAllContacts().isEmpty());
        assertEquals(1, contactManager.getAllContacts().size());
    }

    @DisplayName("CSV Source Case - Phone Number should match the required Format")
    @ParameterizedTest
    @CsvSource({"0123456789", "1234567890", "+0123456789"})
    public void shouldTestPhoneNumberFormatUsingCSVSource(String phoneNumber) {
        contactManager.addContact("John", "Doe", phoneNumber);
        assertFalse(contactManager.getAllContacts().isEmpty());
        assertEquals(1, contactManager.getAllContacts().size());
    }

    @DisplayName("CSV File Source Case - Phone Number should match the required Format")
    @ParameterizedTest
    @CsvFileSource(resources = "/data.csv")
    public void shouldTestPhoneNumberFormatUsingCSVFileSource(String phoneNumber) {
        contactManager.addContact("John", "Doe", phoneNumber);
        assertFalse(contactManager.getAllContacts().isEmpty());
        assertEquals(1, contactManager.getAllContacts().size());
    }
}

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

Если я запущу тесты, вы увидите, что параметризованные тесты отображаются под другим узлом.

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

Мы можем использовать плагин Maven Surefire для выполнения тестов как части сборки, все, что вам нужно сделать, это настроить плагин в pom.xml файл.


    org.apache.maven.plugins
    maven-surefire-plugin
    2.22.2

Вам также следует добавить плагин компилятора Maven для компиляции наших тестовых классов как части сборки.


    org.apache.maven.plugins
    maven-compiler-plugin
    3.8.1
    
        
        15
        
    

Раздел конфигурация компилирует тестовые классы в соответствии с целевой версией JDK.

Если вы используете Java 9+, вам следует просто использовать release метка и если вы используете Java 8, то вам следует раскомментировать исходный код и целевой раздел.

После добавления этих плагинов вы можете запустить тесты с помощью команды mvn clean test

λ mvn clean test
 [INFO] Scanning for projects…
 [INFO]
 [INFO] --------------------< org.example:contact-manager >---------------------
 [INFO] Building contact-manager 1.0-SNAPSHOT
 [INFO] --------------------------------[ jar ]---------------------------------
 [INFO]
 [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ contact-manager ---
 [INFO] Deleting F:\contact-manager\target
 [INFO]
 [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ contact-manager ---
 [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
 [INFO] Copying 0 resource
 [INFO]
 [INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ contact-manager ---
 [INFO] Changes detected - recompiling the module!
 [WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent!
 [INFO] Compiling 2 source files to F:\contact-manager\target\classes
 [INFO]
 [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ contact-manager ---
 [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
 [INFO] Copying 1 resource
 [INFO]
 [INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ contact-manager ---
 [INFO] Changes detected - recompiling the module!
 [WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent!
 [INFO] Compiling 1 source file to F:\contact-manager\target\test-classes
 [INFO]
 [INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ contact-manager ---
 [INFO]
 [INFO] -------------------------------------------------------
 [INFO]  T E S T S
 [INFO] -------------------------------------------------------
 [INFO] Running ContactManagerTest
 Should Print Before All Tests
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Instantiating Contact Manager
 Should Execute After Each Test
 Should be executed at the end of the Test
 [WARNING] Tests run: 24, Failures: 0, Errors: 0, Skipped: 3, Time elapsed: 0.215 s - in ContactManagerTest
 [INFO]
 [INFO] Results:
 [INFO]
 [WARNING] Tests run: 24, Failures: 0, Errors: 0, Skipped: 3
 [INFO]
 [INFO] ------------------------------------------------------------------------
 [INFO] BUILD SUCCESS
 [INFO] ------------------------------------------------------------------------
 [INFO] Total time:  2.813 s
 [INFO] Finished at: 2020-12-26T00:41:57+01:00
 [INFO] ------------------------------------------------------------------------

Итак, мы подошли к концу полного руководства по Junit 5, надеюсь, вы узнали кое-что о Junit 5.

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

Увидимся в следующей статье, а до тех пор Счастливые технари-программисты 🙂

Оригинал: “https://dev.to/saiupadhyayula/junit-5-tutorial-for-beginners-o8a”