React Testing Library (RTL) — это инструмент для тестирования компонентов React, ориентированный на взаимодействие пользователя с приложением, а не на внутреннюю реализацию компонентов. Основная цель RTL — проверять поведение интерфейса так, как его видит пользователь, а не структуру компонентов или состояние их внутренних методов.
Тестирование через пользовательский опыт RTL фокусируется на том, чтобы тесты отражали действия пользователя: клики, ввод текста, навигацию и видимость элементов. Это обеспечивает более устойчивые тесты к изменениям реализации компонентов.
Минимизация тестирования внутренней реализации Не следует проверять приватные методы компонентов или состояние React напрямую. Тесты должны опираться на DOM и видимые элементы, а не на внутренние детали.
Легкость интеграции с Jest и другими фреймворками RTL не предоставляет собственный раннер тестов. Обычно он используется вместе с Jest, что обеспечивает мощные возможности для асинхронного тестирования, мокирования и проверки ожиданий.
render()Функция render создаёт виртуальное представление
компонента в тестовой среде и возвращает объект с методами для
взаимодействия с DOM.
import { render } from '@testing-library/react';
import App from './App';
const { getByText, queryByText } = render(<App />);
Особенности render:
getByText,
getByRole, getByLabelText).RTL предоставляет несколько категорий методов поиска элементов:
getBy…
getByText, getByRole,
getByLabelTextqueryBy…
queryByText, queryByRolenull, если он отсутствует.findBy…
getBy…, возвращают
Promise, который разрешается, когда элемент появляется
в DOM.Пример:
const { getByText, queryByText, findByText } = render(<App />);
expect(getByText('Привет')).toBeInTheDocument();
expect(queryByText('Ошибка')).toBeNull();
await expect(findByText('Загрузка завершена')).resolves.toBeInTheDocument();
user-event)Для симуляции действий пользователя используется библиотека
@testing-library/user-event. Она позволяет выполнять клики,
ввод текста, навигацию по клавиатуре.
import userEvent from '@testing-library/user-event';
const button = getByText('Нажми меня');
userEvent.click(button);
const input = getByLabelText('Имя');
userEvent.type(input, 'Иван');
Преимущества user-event перед
fireEvent:
Тестирование компонентов с асинхронным поведением (запросы к API, таймеры, анимации) требует использования утилит для ожидания. Основные методы:
waitFor — ждет, пока внутри callback
не выполнятся проверки.findBy… — асинхронный поиск элементов
с таймаутом.import { waitFor } from '@testing-library/react';
await waitFor(() => {
expect(getByText('Данные загружены')).toBeInTheDocument();
});
RTL легко интегрируется с контекстами React и библиотеками мокирования, такими как Jest:
import { render } from '@testing-library/react';
import { ThemeProvider } from 'styled-components';
import App from './App';
import theme from './theme';
render(
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>
);
Таким образом, можно тестировать компоненты в среде, максимально приближенной к реальному приложению.
id или className.React Testing Library обеспечивает надёжное тестирование поведения компонентов, делая тесты менее зависимыми от структуры и более ориентированными на реальные сценарии использования. Это помогает создавать стабильные, легко поддерживаемые тесты для React-приложений.