Каков жизненный цикл unit-теста в JUnit?

Ответ

Жизненный цикл unit-теста в JUnit 5 управляется аннотациями и состоит из следующих фаз:

1. Инициализация класса (@BeforeAll):

  • Выполняется один раз перед всеми тестовыми методами в классе.
  • Используется для настройки глобальных ресурсов (подключение к БД, запуск сервера).

2. Подготовка к тесту (@BeforeEach):

  • Выполняется перед каждым тестовым методом.
  • Цель — привести систему в известное состояние (создание чистого экземпляра тестируемого класса, сброс моков).

3. Выполнение теста (@Test):

  • Запускается сам тестовый метод, содержащий вызов тестируемого кода и проверки (assertions).

4. Верификация результатов:

  • Утверждения (assertions) из библиотек JUnit (AssertJ, Hamcrest) проверяют соответствие фактического результата ожидаемому.

5. Очистка после теста (@AfterEach):

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

6. Финализация класса (@AfterAll):

  • Выполняется один раз после всех тестовых методов в классе.
  • Используется для освобождения глобальных ресурсов (остановка сервера, разрыв соединения с БД).

Пример на Java (JUnit 5):

import org.junit.jupiter.api.*;

class CalculatorTest {
    private Calculator calculator;

    @BeforeAll
    static void initAll() {
        System.out.println("Инициализация перед всеми тестами");
    }

    @BeforeEach
    void init() {
        calculator = new Calculator(); // Чистый экземпляр перед каждым тестом
    }

    @Test
    void testAddition() {
        int result = calculator.add(2, 3);
        Assertions.assertEquals(5, result); // Проверка (assertion)
    }

    @AfterEach
    void tearDown() {
        calculator = null; // Очистка ссылки
    }

    @AfterAll
    static void tearDownAll() {
        System.out.println("Финализация после всех тестов");
    }
}

Ответ 18+ 🔞

А, ну вот, жизненный цикл теста, блядь! Это ж святое, ёпта. Сейчас разжуём, как сука, по полочкам, чтобы даже мартышлюшка поняла.

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

1. Разгон всей лаборатории (@BeforeAll): Это ты, сука, включаешь свет во всём здании, запускаешь центральный генератор и говоришь «Ребятки, начинаем!». Выполняется один раз на всех, до того как первый тест пальцем пошевелит. Идеально, чтобы базу данных поднять или сервак запустить, а то потом охуевать будешь, что всё падает.

2. Подготовка стола перед каждым опытом (@BeforeEach): Перед тем как смешивать реактивы, ты, блядь, вытираешь стол начисто. Каждый раз! Выкидываешь прошлые ошмётки, ставишь новый чистый стаканчик (экземпляр класса) и кладёшь свежие инструменты. Чтобы тест стартовал с чистого листа, а не с грязных следов от предыдущего мудака.

3. Самый момент истины — взрыв (@Test): А вот тут ты, сука, проводишь свой опыт. Вызываешь метод, кидаешь в него данные и смотришь, что будет. Главное — не обосраться от волнения.

4. Проверка, не разнесло ли пол-лаборатории (Верификация): После взрыва смотришь: получился ли ожидаемый гриб? Или ты просто себе бошки оторвал? Для этого есть assertions — они как приборы, которые показывают, сошёлся ли результат с прогнозом или пора бежать, блядь, в укрытие.

5. Уборка говна после себя (@AfterEach): Опыт закончился. Неважно, успешный или пиздецкий. Ты обязан, блядь, смести осколки, вылить остатки кислоты и помыть колбы. Чтобы следующий тест не начал свою жизнь в луже твоего позавчерашнего кода.

6. Закрытие лаборатории на ночь (@AfterAll): Все эксперименты завершены. Теперь можно, сука, вырубить генератор, потушить свет и закрыть базу данных на ключ. Выполняется один раз, когда уже все разбежались.

А теперь, блядь, смотри, как это выглядит в коде, чтобы не быть просто пиздаболом:

import org.junit.jupiter.api.*;

class CalculatorTest {
    private Calculator calculator; // Наш подопытный кролик

    @BeforeAll
    static void initAll() {
        System.out.println("Включаем центральное питание нахуй!");
    }

    @BeforeEach
    void init() {
        calculator = new Calculator(); // Каждый раз новый, свеженький, не засранный
    }

    @Test
    void testAddition() {
        int result = calculator.add(2, 3); // Проводим опыт
        Assertions.assertEquals(5, result); // Сверяем с теорией. Не сошлось? Пиздец тебе.
    }

    @AfterEach
    void tearDown() {
        calculator = null; // Выкидываем кролика в мусорку, эксперимент окончен
    }

    @AfterAll
    static void tearDownAll() {
        System.out.println("Гасим свет, закрываемся, идём бухать.");
    }
}

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