Тестирование сценариев пользователя (или user scenarios) — это важная часть процесса тестирования, которая направлена на проверку того, как приложение будет вести себя в реальных условиях. Jest предоставляет удобные инструменты для создания таких тестов, которые симулируют действия пользователей и позволяют выявить ошибки и улучшить качество кода. В этой части рассмотрим, как правильно тестировать сценарии пользователя с использованием Jest, начиная от базовых концепций до более сложных случаев.
Для начала необходимо определиться с тем, что представляет собой пользовательский сценарий. Это последовательность действий, которые пользователь выполняет в приложении. Например, для веб-приложения это может быть процесс регистрации, отправка формы или взаимодействие с динамическим контентом. Сценарии могут быть простыми или сложными, но важно, чтобы они отражали реальные действия пользователей.
Для тестирования таких сценариев потребуется:
Jest поможет организовать тесты с использованием mock-функций,
симуляции событий и проверки состояний компонентов. Один из самых
удобных инструментов для работы с такими тестами в Jest — это
использование библиотек, таких как @testing-library/react,
которая предоставляет функции для удобной работы с DOM и симуляции
действий пользователя.
Для тестирования взаимодействий пользователя с интерфейсом часто требуется симуляция кликов, ввода текста и других действий. Jest предоставляет несколько способов для этого.
Пример теста, который имитирует клики и ввод текста:
import { render, screen, fireEvent } from '@testing-library/react';
import UserForm from './UserForm';
test('Пользователь успешно отправляет форму', () => {
render(<UserForm />);
// Симуляция ввода текста в поля формы
fireEvent.change(screen.getByLabelText(/Имя/i), { target: { value: 'Иван' } });
fireEvent.change(screen.getByLabelText(/Email/i), { target: { value: 'ivan@mail.com' } });
// Симуляция отправки формы
fireEvent.click(screen.getByText(/Отправить/i));
// Проверка состояния компонента после отправки
expect(screen.getByText(/Форма отправлена/i)).toBeInTheDocument();
});
В данном примере используется библиотека
@testing-library/react для рендеринга компонента и
симуляции действий пользователя, таких как ввод текста и клик по кнопке.
После выполнения этих действий проверяется, что форма была отправлена и
что отображается соответствующее сообщение.
В более сложных сценариях может потребоваться тестирование нескольких взаимодействий между пользователем и приложением, а также проверка различных состояний системы. Например, необходимо проверить, что происходит при отправке формы с ошибочными данными или как приложение обрабатывает ответ от сервера.
Пример теста для проверки обработки ошибок:
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import UserForm from './UserForm';
import { postData } from './api'; // Функция для отправки данных
jest.mock('./api'); // Мокаем функцию postData
test('Обработка ошибки при отправке формы', async () => {
render(<UserForm />);
fireEvent.change(screen.getByLabelText(/Имя/i), { target: { value: 'Иван' } });
fireEvent.change(screen.getByLabelText(/Email/i), { target: { value: 'ivan@mail.com' } });
postData.mockRejectedValueOnce(new Error('Сервер недоступен'));
fireEvent.click(screen.getByText(/Отправить/i));
await waitFor(() => {
expect(screen.getByText(/Ошибка при отправке данных/i)).toBeInTheDocument();
});
});
Здесь мы используем Jest для мокирования внешней функции
postData, которая отправляет данные на сервер. Мы создаем
сценарий, при котором сервер возвращает ошибку, и проверяем, как
компонент реагирует на эту ошибку, отображая соответствующее сообщение
пользователю.
Часто в реальных приложениях взаимодействие с сервером или внешними
сервисами является асинхронным. Jest позволяет легко работать с такими
случаями, используя методы, такие как async и
await. Для асинхронных операций важно использовать утилиты
Jest для ожидания завершения работы асинхронных действий перед проверкой
результатов.
Пример асинхронного теста с использованием async и
await:
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import UserForm from './UserForm';
import { fetchUserData } from './api';
jest.mock('./api');
test('Загрузка данных пользователя перед отправкой формы', async () => {
render(<UserForm />);
fetchUserData.mockResolvedValueOnce({ name: 'Иван', email: 'ivan@mail.com' });
// Симуляция загрузки данных пользователя
fireEvent.click(screen.getByText(/Загрузить данные/i));
await waitFor(() => expect(screen.getByText(/Имя: Иван/i)).toBeInTheDocument());
await waitFor(() => expect(screen.getByText(/Email: ivan@mail.com/i)).toBeInTheDocument());
});
В этом примере мы мокаем функцию fetchUserData, которая
асинхронно загружает данные пользователя. Мы проверяем, что после
загрузки данных соответствующая информация отображается на экране.
Часто в процессе тестирования необходимо убедиться, что состояние
приложения корректно меняется в ответ на действия пользователя. Jest в
сочетании с @testing-library/react предоставляет удобные
средства для работы с состоянием и проверки его изменений. Состояние
компонента может меняться как в результате действий пользователя, так и
в ответ на асинхронные запросы.
Пример теста, проверяющего изменение состояния:
import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './Counter';
test('Пользователь увеличивает счётчик', () => {
render(<Counter />);
// Проверка начального значения счётчика
expect(screen.getByText(/Счётчик: 0/i)).toBeInTheDocument();
// Симуляция клика по кнопке увеличения
fireEvent.click(screen.getByText(/Увеличить/i));
// Проверка изменения состояния после клика
expect(screen.getByText(/Счётчик: 1/i)).toBeInTheDocument();
});
Здесь проверяется, что состояние счётчика изменяется после клика по кнопке. Этот тест демонстрирует, как можно проверять взаимодействие с компонентом, который имеет внутреннее состояние.
В реальных приложениях пользователи часто выполняют сложные действия, которые включают несколько шагов. Тестирование таких сценариев может потребовать проверки различных состояний, переходов между экранами и обработки различных состояний ошибок. В таких случаях полезно создавать интеграционные тесты, которые проверяют, как разные части приложения взаимодействуют друг с другом.
Пример сложного сценария:
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import CheckoutPage from './CheckoutPage';
jest.mock('./api');
test('Пользователь проходит весь процесс оформления заказа', async () => {
render(<CheckoutPage />);
// Шаг 1: Ввод данных о доставке
fireEvent.change(screen.getByLabelText(/Имя/i), { target: { value: 'Иван' } });
fireEvent.change(screen.getByLabelText(/Адрес/i), { target: { value: 'Москва, ул. Пушкина, д. 10' } });
// Шаг 2: Выбор метода оплаты
fireEvent.click(screen.getByText(/Кредитная карта/i));
// Шаг 3: Отправка данных
fireEvent.click(screen.getByText(/Оформить заказ/i));
// Проверка завершения оформления заказа
await waitFor(() => expect(screen.getByText(/Заказ успешно оформлен/i)).toBeInTheDocument());
});
Здесь тестируется процесс оформления заказа, который включает несколько шагов. Для каждого шага проверяется, что состояние компонента соответствует ожиданиям, а в конце показывается сообщение о успешном оформлении заказа.
Тестирование сценариев пользователя — это важный аспект обеспечения
качества веб-приложений, который позволяет убедиться в том, что
приложение работает так, как ожидается, при реальных условиях
использования. Jest и вспомогательные библиотеки, такие как
@testing-library/react, позволяют легко симулировать
действия пользователя и проверять различные состояния компонентов.
Создание тестов для пользовательских сценариев помогает улучшить
качество кода, ускорить процесс разработки и предотвратить появление
багов.