Testing Library — это инструмент для тестирования компонентов, ориентированный на работу с интерфейсом, а не на внутренние детали реализации. В контексте Preact он обеспечивает удобный способ проверки того, как компоненты рендерятся, взаимодействуют с пользователем и реагируют на изменения состояния.
Ключевая цель: проверка поведения компонентов так, как это делает пользователь, а не тестирование их внутреннего устройства.
Для работы с Testing Library в Preact требуется несколько пакетов:
npm install @testing-library/preact @testing-library/jest-dom --save-dev
@testing-library/preact — обеспечивает рендеринг
Preact-компонентов для тестирования.@testing-library/jest-dom — добавляет удобные матчеры
для Jest, позволяя писать более читаемые утверждения, например
toBeVisible() или toHaveTextContent().Настройка может включать интеграцию с Jest. В файле
setupTests.js подключается jest-dom:
import '@testing-library/jest-dom';
Основная функция для тестирования компонентов — render.
Она позволяет отрендерить компонент и получить удобные методы для поиска
элементов в DOM:
import { render } from '@testing-library/preact';
import MyComponent from './MyComponent';
test('рендерит текст', () => {
const { getByText } = render(<MyComponent />);
expect(getByText('Привет, Preact!')).toBeInTheDocument();
});
Методы поиска элементов:
getByText — ищет элемент по текстовому содержимому,
выбрасывает ошибку, если элемент не найден.queryByText — возвращает null, если
элемент отсутствует, удобен для проверки отрицательных сценариев.findByText — асинхронная версия, возвращает промис,
ожидающий появления элемента.Testing Library позволяет имитировать действия пользователя через
пакет user-event:
npm install @testing-library/user-event --save-dev
Пример клика по кнопке и проверки эффекта:
import { render, screen } from '@testing-library/preact';
import userEvent from '@testing-library/user-event';
import Counter from './Counter';
test('увеличивает счетчик при клике', async () => {
render(<Counter />);
const button = screen.getByRole('button', { name: /увеличить/i });
await userEvent.click(button);
expect(screen.getByText('Счет: 1')).toBeInTheDocument();
});
Методы взаимодействия:
userEvent.click(element) — симуляция клика.userEvent.type(element, text) — ввод текста в
поле.userEvent.selectOptions(select, option) — выбор
значения в <select>.Компоненты Preact часто используют асинхронные операции, например загрузку данных. Testing Library предоставляет удобные утилиты для ожидания изменений DOM:
waitFor — ожидает выполнения условия:import { render, screen, waitFor } from '@testing-library/preact';
import AsyncComponent from './AsyncComponent';
test('отображает данные после загрузки', async () => {
render(<AsyncComponent />);
await waitFor(() => expect(screen.getByText('Данные загружены')).toBeInTheDocument());
});
findBy* — сокращает использование waitFor,
возвращает промис, который разрешается при появлении элемента.По умолчанию render создает контейнер для компонента и
автоматически очищает его после теста. Если требуется кастомный
контейнер:
import { render } from '@testing-library/preact';
const container = document.createElement('div');
document.body.appendChild(container);
render(<MyComponent />, { container });
В большинстве случаев ручной cleanup не требуется, но
его можно вызвать через:
import { cleanup } from '@testing-library/preact';
afterEach(cleanup);
Testing Library проверяет компонент «как есть», но можно легко обновлять пропсы и проверять реакцию:
import { render, screen } from '@testing-library/preact';
import { h } from 'preact';
import Greeting from './Greeting';
test('изменяет приветствие при изменении пропсов', () => {
const { rerender } = render(<Greeting name="Алексей" />);
expect(screen.getByText('Привет, Алексей')).toBeInTheDocument();
rerender(<Greeting name="Мария" />);
expect(screen.getByText('Привет, Мария')).toBeInTheDocument();
});
rerender полезен для проверки динамических обновлений
без полного повторного рендера.
Testing Library стимулирует использование доступности:
getByRole — ищет элементы по их семантической роли
(button, textbox, heading).getByLabelText — ищет элементы формы по связанной метке
<label>.getByPlaceholderText — ищет элементы формы по
placeholder.Применение этих методов делает тесты более стабильными и ближе к поведению пользователя.
Hooks Preact (useState, useEffect,
useRef) полностью поддерживаются Testing Library.
Асинхронные эффекты и обновления состояния корректно обрабатываются при
использовании waitFor или findBy*.
import { render, screen, waitFor } from '@testing-library/preact';
import Timer from './Timer';
test('отображает увеличивающееся время', async () => {
render(<Timer />);
await waitFor(() => expect(screen.getByText(/Время: \d+/)).toBeInTheDocument());
});
Для тестов компонентов с API-запросами используется мокирование через Jest:
jest.mock('../api', () => ({
fetchData: jest.fn(() => Promise.resolve('Данные загружены'))
}));
Это позволяет полностью контролировать данные и предсказуемо тестировать поведение компонентов.
Testing Library для Preact обеспечивает подход к тестированию, сосредоточенный на поведении пользователя, совместим с современными инструментами Preact, включая хуки и асинхронные эффекты, и предлагает удобные утилиты для рендера, взаимодействия и ожидания изменений в DOM.