Integration тестирование

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

Инструменты для интеграционного тестирования

Наиболее популярными инструментами для тестирования Preact-приложений являются:

  • Jest — фреймворк для запуска тестов и проверки ожидаемого поведения компонентов.
  • @testing-library/preact — библиотека для рендеринга компонентов и взаимодействия с ними через DOM, обеспечивающая работу с виртуальной средой, близкой к реальному поведению браузера.
  • Sinon или jest.fn() — для создания моков и шпионов на функции.

Использование этих инструментов позволяет моделировать пользовательские сценарии, проверять корректность вызова callback-функций и управлять состоянием приложения.

Структура интеграционного теста

Типичный интеграционный тест в Preact включает следующие шаги:

  1. Подготовка окружения: импорт компонентов, создание моков и настройка тестового DOM.
  2. Рендеринг компонентов: использование render из @testing-library/preact для встраивания компонентов в виртуальный DOM.
  3. Взаимодействие с компонентами: симуляция пользовательских действий с помощью fireEvent или userEvent.
  4. Проверка результата: ассерты через expect для оценки состояния компонентов, наличия элементов в DOM и вызова функций.

Пример интеграционного теста

import { h } from 'preact';
import { render, fireEvent } from '@testing-library/preact';
import App from './App';

test('кнопка увеличивает счетчик при клике', () => {
  const { getByText } = render(<App />);
  
  const button = getByText('Увеличить');
  const counter = getByText('Счетчик: 0');

  fireEvent.click(button);

  expect(counter.textContent).toBe('Счетчик: 1');
});

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

Работа с асинхронными компонентами

Для компонентов, использующих useEffect или асинхронные вызовы, необходимо применять waitFor из @testing-library/preact, чтобы дождаться завершения всех эффектов:

import { waitFor } from '@testing-library/preact';

test('данные загружаются и отображаются', async () => {
  const { getByText } = render(<AsyncDataComponent />);
  
  await waitFor(() => getByText('Данные загружены'));
  
  expect(getByText('Данные загружены')).toBeInTheDocument();
});

Тестирование передачи props и событий

Интеграционные тесты Preact часто проверяют корректность передачи props и работу событий:

test('компонент вызывает callback при изменении ввода', () => {
  const handleChange = jest.fn();
  const { getByPlaceholderText } = render(<InputComponent onCha nge={handleChange} />);
  
  const input = getByPlaceholderText('Введите текст');
  fireEvent.input(input, { target: { value: 'Тест' } });
  
  expect(handleChange).toHaveBeenCalledWith('Тест');
});

Стратегии организации тестов

  • Тестирование пользовательских сценариев: создание тестов, ориентированных на реальные действия пользователей, таких как ввод данных, навигация между страницами и отправка форм.
  • Компонентные тесты с интеграцией: проверка работы нескольких взаимосвязанных компонентов без полного запуска приложения.
  • Мокирование внешних зависимостей: API-запросов, локального хранилища, контекста приложения для изоляции тестируемого поведения.

Полезные советы

  • Использовать screen из @testing-library/preact для более читаемых тестов.
  • Предпочитать userEvent вместо fireEvent для симуляции действий пользователя, поскольку он учитывает естественные события браузера.
  • Стремиться к тестированию реальных сценариев, а не внутренних реализаций, чтобы интеграционные тесты оставались стабильными при рефакторинге.

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