Введение
Моки
Моки (от англ. Mock) — это фальшивые реализации запросов или данных. Если проводить аналогию, мок — это актер, играющий роль API, который всегда отвечает так, как мы хотим. Представьте, что реальный сервер взял отпуск, но мы наняли дублера, который исполняет его обязанности.
Моки позволяют:
- Имитировать API-запросы, даже если сервер недоступен.
- Тестировать приложения независимо от внешних сервисов.
- Проверять поведение приложения в разных сценариях (например, успешный ответ или ошибка сервера).
Фикстуры
Фикстуры — это заранее подготовленные наборы данных. Если моки — это актеры, то фикстуры — это написанные на бумаге сценарии, которые всегда остаются одинаковыми. В контексте Cypress, фикстуры — это статические файлы (например, JSON), которые мы используем как ответы API.
Фикстуры:
- Снижают сложность написания тестов (нет необходимости каждый раз генерировать данные).
- Упрощают повторяемость тестов (одни и те же данные для всех прогонов).
- Обеспечивают стабильность, так как не зависят от реальных внешних данных.
Создание и настройка фикстур в Cypress
Шаг 1: подготовка фикстуры
Cypress по умолчанию уже настроен для работы с фикстурами. Все фикстуры хранятся в папке cypress/fixtures. Давайте создадим простую фикстуру для имитации API-ответа.
Создайте файл user.json в папке cypress/fixtures:
{
"id": 1,
"name": "Иван Иванов",
"email": "ivan.ivanov@example.com"
}
Этот файл будет фикстурой, которую мы будем использовать в тестах.
Шаг 2: использование фикстуры в тестах
Теперь напишем тест, который проверит, как приложение обрабатывает данные от API. Вместо реального API мы используем нашу фикстуру.
Создайте файл api_request.spec.js в папке cypress/e2e:
describe('Тестирование API с использованием фикстур', () => {
it('Загружает данные пользователя из фикстуры', () => {
// Перехватываем запросы и подменяем ответ фикстурой
cy.intercept('GET', '/api/user', { fixture: 'user.json' }).as('getUser');
// Заходим на главную страницу
cy.visit('/');
// Проверяем загрузку данных
cy.wait('@getUser');
cy.get('[data-testid="username"]').should('contain', 'Иван Иванов');
cy.get('[data-testid="email"]').should('contain', 'ivan.ivanov@example.com');
});
});
Здесь мы:
- Используем
cy.intercept()для перехвата запросов по маршруту/api/user. - Задаем фикстуру как ответ для этого маршрута.
- Проверяем, что интерфейс приложения корректно показывает данные.
Шаг 3: почему это работает?
Мы полностью исключили реальное API из теста. Вместо бекенда Cypress "подыгрывает" приложению и подставляет данные из фикстуры. Это удобно для тестирования UI, ведь мы можем быть уверены, что данные не изменятся.
Реализация и использование моков в тестах
Шаг 1: создание мока
Моки не обязательно должны быть файлами. Мы можем динамически создавать данные прямо в тестах. Например, представим, что мы хотим протестировать сценарий, когда API возвращает ошибку.
describe('Тестирование API с использованием мока', () => {
it('Обрабатывает сценарий 500 Internal Server Error', () => {
// Перехватываем запросы и подменяем ответ ошибкой
cy.intercept('GET', '/api/user', {
statusCode: 500,
body: { error: 'Internal Server Error' }
}).as('getUserError');
// Заходим на главную страницу
cy.visit('/');
// Проверяем, что приложение корректно обработало ошибку
cy.wait('@getUserError');
cy.get('[data-testid="error-message"]').should('contain', 'Ошибка загрузки данных');
});
});
Как это работает:
statusCodeзадает HTTP-код ответа.bodyсодержит тело ответа (в данном случае сообщение об ошибке).- Мы проверяем, что интерфейс корректно показывает сообщение об ошибке.
Шаг 2: моки для различных сценариев
Моки позволяют тестировать все возможные состояния API:
- Успешный ответ (200),
- Ошибка клиента (400),
- Ошибка сервера (500),
- Пустой ответ и так далее.
Пример:
cy.intercept('GET', '/api/user', (req) => {
req.reply((res) => {
res.send({
statusCode: 404,
body: { error: 'User Not Found' }
});
});
}).as('getUserNotFound');
В этом сценарии мы симулировали 404 Not Found.
Использование фикстур и моков вместе
Фикстуры и моки можно комбинировать для тестирования сложных сценариев.
Пример: вы хотите использовать фикстуру, но с небольшим изменением данных.
describe('Комбинированное использование фикстур и моков', () => {
it('Модифицирует фикстуру перед использованием', () => {
cy.fixture('user.json').then((user) => {
user.name = 'Алексей Петров';
cy.intercept('GET', '/api/user', user).as('getUserModified');
});
cy.visit('/');
cy.wait('@getUserModified');
cy.get('[data-testid="username"]').should('contain', 'Алексей Петров');
});
});
Тут мы:
- Загружаем фикстуру.
- данные в коде.
- Используем модифицированную фикстуру в моке.
Где нужны моки и фикстуры?
На практике вы будете часто использовать моки и фикстуры для:
- Ускорения тестов: реальный API может быть медленным.
- Тестирования редких или сложных сценариев (например, сбои сервера).
- Тестирования без зависимости от внешних сервисов.
- Создания изолированной среды.
Ошибки, которые нужно избегать
Работа с моками и фикстурами может быть непростой. Вот несколько распространенных ошибок:
- Забыть об обновлении фикстуры: если API изменилось, фикстуры устаревают и становятся бесполезными.
- Чрезмерное использование моков: иногда важно протестировать реальное API.
- Неправильное перехватывание запросов: всегда проверяйте, что маршрут (URL) в
cy.intercept()совпадает с фактическим.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ