userEvent — это утилита для симуляции действий
пользователя в тестах на React, предоставляемая пакетом
@testing-library/user-event. Она расширяет возможности
стандартного fireEvent, предоставляя более реалистичное
поведение: клики, ввод текста, наведение мыши, выбор элементов и другие
пользовательские взаимодействия.
Для работы с userEvent необходимо установить
соответствующий пакет:
npm install --save-dev @testing-library/user-event
Импортировать модуль следует следующим образом:
import userEvent from '@testing-library/user-event';
В последних версиях пакета userEvent создается как
объект с методами через фабрику, что позволяет конфигурировать его
поведение:
const user = userEvent.setup();
Использование setup() важно, так как оно поддерживает
асинхронные действия и позволяет задавать глобальные настройки,
например, задержку между действиями, моделируя реальные пользовательские
события.
userEventuserEvent.setup() принимает объект с опциями
конфигурации. Основные параметры:
delay — время задержки между симулируемыми событиями, полезно для тестирования пользовательских ожиданий и анимаций.
const user = userEvent.setup({ delay: 100 });
Здесь ввод текста или клики будут происходить с задержкой 100 миллисекунд между событиями.
pointerEventsCheck — включает проверку событий
указателя. По умолчанию true, что предотвращает выполнение
событий на неактивных или скрытых элементах.
keyboardMap — позволяет задать собственную раскладку клавиатуры, если требуется тестировать ввод с нестандартной локалью или специальные символы.
advanceTimers — функция для контроля таймеров
при использовании jest.useFakeTimers() или аналогичных
инструментов. Позволяет корректно симулировать асинхронные
действия.
Пример комплексной настройки:
const user = userEvent.setup({
delay: 50,
pointerEventsCheck: true,
advanceTimers: jest.advanceTimersByTime
});
userEvent
в тестахМетоды userEvent полностью асинхронны и требуют
использования await при взаимодействии с элементами:
import { render, screen } from '@testing-library/react';
import MyForm from './MyForm';
test('пользователь вводит текст и отправляет форму', async () => {
const user = userEvent.setup();
render(<MyForm />);
const input = screen.getByLabelText(/имя/i);
const button = screen.getByRole('button', { name: /отправить/i });
await user.type(input, 'Иван');
await user.click(button);
expect(screen.getByText(/Спасибо, Иван!/i)).toBeInTheDocument();
});
Особенности:
user.type(element, text) имитирует ввод текста, вызывая
события keydown, keypress, input,
keyup.user.click(element) вызывает последовательность событий
mousedown, mouseup, click.user.hover(element) и
user.unhover(element) позволяют тестировать реакции на
наведение мыши.userEvent и fireEventfireEvent просто генерирует одно событие на
элементе:
fireEvent.click(button);
userEvent симулирует полный цикл действий пользователя,
включая все промежуточные события и состояние браузера:
await user.click(button);
Преимущества:
Так как современные интерфейсы часто используют асинхронные
обновления состояния, userEvent обеспечивает корректное
выполнение цепочек событий. Любой метод возвращает промис, который можно
await:
await user.type(input, 'Тест');
await user.click(submitButton);
Это гарантирует, что состояние компонента будет актуальным после каждого действия, и тест не упадет из-за несинхронных обновлений.
userEvent идеально сочетается с screen и
render, предоставляя единый инструмент для:
getByRole,
getByLabelText, getByText).await для всех методов
userEvent.user = userEvent.setup() с конфигурацией.userEvent вместо fireEvent,
если необходимо имитировать реальные действия пользователя.delay только при необходимости
моделирования реального ввода, чтобы не замедлять тесты без
причины.pointerEventsCheck, чтобы избежать ложноположительных
результатов.Использование userEvent позволяет создавать тесты,
максимально приближенные к реальному поведению пользователя, и
значительно повышает надежность проверок UI-компонентов в React.