Написание unit-тестов для различных сценариев работы приложения

Сложность: hard Тема: TES
junit unit-тесты классы эквивалентности сценарное тестирование паттерны

Контекст задачи

Реальные приложения содержат классы с несколькими методами и множеством сценариев использования. Каждый метод может иметь несколько путей выполнения: успешный, альтернативный, исключительный. Покрытие всех путей только ручным тестированием невозможно — unit-тесты дают структурное покрытие и гарантируют, что каждый путь проверен. Для классов, реализующих паттерны (Итератор, Стратегия, Наблюдатель), это особенно критично.

Формулировка

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

Ожидаемый результат

  • Класс тестов в папке src/test/java с минимум 3 тестируемыми методами
  • Для каждого метода: тест на успешный путь + тест на альтернативный/ошибочный путь
  • Код тестируемого класса (из проекта) в отчёте
  • Тесты на корректный интерфейс (проверка состояний после вызова метода)
  • Тесты на ошибочные условия (исключения, некорректные данные)
  • Покрытие двух и более путей в каждом методе

Инструментарий

Методы и подходы:

  • Определение классов эквивалентности для каждого метода
  • Тест успешного пути (основной поток)
  • Тест альтернативного пути (например, конец коллекции, пустая коллекция)
  • Тест ошибочного условия (исключение, невалидный ввод)
  • Тест состояния интерфейса (проверка полей/состояния после вызова)
  • Покрытие путей: измерение ветвей в методах (cyclomatic complexity)
  • Заглушки (mocks) для зависимых компонентов

Инструменты:

  • IntelliJ IDEA (Alt+Enter → «Create Test»)
  • JUnit 5
  • Mockito (для заглушек, опционально)
  • Maven/Gradle (зависимости на JUnit и Mockito)

Навигатор

  • [Пример unit-тестов для Итератора]
  • [Примеры тест-кейсов для Click-игр]
  • Вопрос: Сколько разных «путь» проходит каждый метод вашего класса? Какой из них проверяется по умолчанию и какой — чаще всего забывается?
  • Пример для паттерна Итератор (программа «Слайды»):
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class SlidesIteratorTest {
    private Slides slides;

    @BeforeEach
    void setUp() {
        slides = new Slides();
        slides.addSlide(new Slide("Slide 1"));
        slides.addSlide(new Slide("Slide 2"));
        slides.addSlide(new Slide("Slide 3"));
    }

    // Сценарий 1: Показать следующий слайд — слайд существует
    @Test
    void testNextSlideExists() {
        assertEquals("Slide 1", slides.next().getTitle());
        assertEquals("Slide 2", slides.next().getTitle());
    }

    // Сценарий 1: Показать следующий слайд — конец коллекции
    @Test
    void testNextSlideEndOfCollection() {
        slides.next(); slides.next(); slides.next(); //已到最后一个
        assertThrows(NoSuchElementException.class, slides::next);
    }

    // Сценарий 2: Перейти на первый слайд — не текущий
    @Test
    void testFirstSlideNotCurrent() {
        slides.next();
        slides.first();
        assertEquals("Slide 1", slides.getCurrent().getTitle());
    }

    // Сценарий 3: Перейти на последний слайд — текущий
    @Test
    void testLastSlideIsCurrent() {
        slides.last();
        assertEquals("Slide 3", slides.getCurrent().getTitle());
    }

    // Сценарий 4: Предыдущий слайд — начало коллекции
    @Test
    void testPreviousSlideBeginning() {
        slides.first();
        assertThrows(NoSuchElementException.class, slides::previous);
    }
}

📝 Критерии оценки

  • Тестовый класс содержит минимум 3 тестируемых метода
  • Для каждого метода проверен успешный сценарий (основной поток)
  • Для каждого метода проверен альтернативный или ошибочный сценарий
  • Реализованы тесты на состояние интерфейса (проверка полей после вызова)
  • Реализованы тесты на ошибочные условия (исключения, невалидные данные)
  • Покрыты два и более путей в каждом тестируемом методе
  • Код тестируемого класса предоставлен (или размещён в GitHub-проекте)
  • Все тесты проходят (зелёный статус)