При тестировании React-компонентов, содержащих текстовые поля
(input, textarea), ключевой задачей является
имитация поведения пользователя: ввод текста, очистка поля или выделение
всего содержимого. React Testing Library предоставляет для этого удобные
утилиты, встроенные в модуль user-event, позволяющий
моделировать действия максимально близко к реальному взаимодействию.
1. type
Метод type используется для ввода текста в текстовое
поле. Он эмулирует печать пользователя, учитывая каждый введённый
символ. В отличие от простого изменения значения через
fireEvent.change, type вызывает все
соответствующие события (keydown, keypress,
input, keyup), что делает тесты более
реалистичными.
Пример использования:
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import TextInput from './TextInput';
test('ввод текста в input', async () => {
render(<TextInput />);
const input = screen.getByRole('textbox');
await userEvent.type(input, 'Привет');
expect(input).toHaveValue('Привет');
});
Особенности type:
{delay: 100}).{enter}, {backspace},
{tab}).onChange и другие обработчики.2. clear
Метод clear полностью очищает содержимое текстового
поля. Важно понимать, что clear вызывает события так же,
как если бы пользователь удалял текст вручную, что позволяет тестам
корректно реагировать на изменения состояния.
Пример использования:
test('очистка input', async () => {
render(<TextInput value="Тестовое значение" />);
const input = screen.getByRole('textbox');
await userEvent.clear(input);
expect(input).toHaveValue('');
});
Особенности clear:
backspace.type для проверки
последовательного ввода и удаления текста.3. selectAll
Метод selectAll позволяет выделить весь текст в поле
ввода, аналогично действиям пользователя с Ctrl+A или
Cmd+A. Это особенно полезно при реализации функциональности
замены текста или проверки поведения при вставке нового значения поверх
выделенного.
Пример использования:
test('выделение всего текста и замена', async () => {
render(<TextInput value="Старый текст" />);
const input = screen.getByRole('textbox');
await userEvent.selectOptions(input); // selectAll нет в user-event v14, используется комбинация selectText
await userEvent.type(input, 'Новый текст');
expect(input).toHaveValue('Новый текст');
});
Особенности selectAll:
type, чтобы заменить
полностью старое значение новым.user-event: в последних
версиях выделение текста может выполняться через
input.select() перед вводом текста.Эффективное тестирование текстовых полей обычно сочетает три метода:
test('комбинация type, clear и selectAll', async () => {
render(<TextInput value="Исходный текст" />);
const input = screen.getByRole('textbox');
// Очистка поля
await userEvent.clear(input);
expect(input).toHaveValue('');
// Ввод нового текста
await userEvent.type(input, 'Первый ввод');
expect(input).toHaveValue('Первый ввод');
// Выделение и замена текста
input.select();
await userEvent.type(input, 'Замена текста');
expect(input).toHaveValue('Замена текста');
});
Такой подход позволяет моделировать реальные сценарии взаимодействия пользователя: редактирование, удаление, выделение и вставку текста.
userEvent вместо
fireEvent для имитации действий пользователя, так
как это обеспечивает корректное срабатывание всех событий.value напрямую через
свойство input.value, если цель — проверить реакцию
компонентов на действия пользователя.userEvent возвращают промис, поэтому необходимо
использовать await.Работа с текстовыми полями через type,
clear и selectAll обеспечивает тестам высокую
реалистичность и позволяет проверять компонент так, как его видит
реальный пользователь. Это повышает качество тестирования форм, поиска,
чатов и других интерфейсов, где важен ввод текста.