Во время тестирования, фронтенд тестируемого приложения, почти наверняка, взаимодействует с бекендом для отправки форм и запроса данных. В некоторых случая, когда тестируется приложение целиком, это не составляет проблемы, но иногда, приложение тестируется в изоляции, либо часть запросов не может быть выполнена и их нужно каким-то образом подменить.
В Playwright можно легко создавать mock API, что позволяет тестировать ваше приложение в контролируемой среде без реального взаимодействия с внешними сервисами. Это особенно полезно, когда вы хотите проверить поведение вашего приложения при различных ответах от сервера, например, при успешном ответе, ошибке или таймауте.
Mock APIs
Mock API в Playwright работает через перехват запросов. Вы можете настроить свой тестовый сценарий так, чтобы он перехватывал запросы к определённому URL и отвечал на них данными, которые вы определяете вручную. Это делается с помощью метода page.route()
.
Предположим, у вас есть приложение, которое делает запрос к API для получения списка пользователей при загрузке страницы. Вот пример того, как вы можете замокировать этот запрос в Playwright:
import { test, expect } from '@playwright/test'
test('mock API example', async ({ page }) => {
// Создаём mock для запроса
// */** - позволяет не указывать домен
await page.route('*/**/users', (route) => {
// Ответ, который будет отправлен вместо реального запроса
const json = [
{ id: 1, firstName: 'Alice', lastName: 'Johnson', email: 'alicejohnson@email.com' },
{ id: 2, firstName: 'Bob', lastName: 'Smith', email: 'bobsmith@email.com' },
]
// Ответить mock данными с кодом 200 (успех)
route.fulfill({ json })
})
// Открываем страницу, которая делает запрос к API
await page.goto('https://http.hexlet.app/js-playwright/users-list')
// Проверяем, что mock данные правильно отобразились на странице
const userNames = await page.getByRole('listitem').allTextContents()
await expect(userNames).toEqual(['Alice Johnson alicejohnson@email.com', 'Bob Smith bobsmith@email.com'])
})
Создание мока происходит до выполнения действия, которое выполняет запрос иначе мок не сработает. Сам запрос перехватывается и на сервер ничего не уходит, но приложение об этом ничего не знает, для него запрос проходит успешно и возвращает какие-то данные. Дальше все работает как обычно.
Мок (mock) в Playwright работает, в рамках одного теста, до тех пор, пока вы не снимете его вручную или не завершите тест. Иными словами, каждый раз, когда приложение отправляет запрос, соответствующий маршруту, который вы перехватили с помощью page.route, Playwright будет использовать ваш мок.
Если нужно снять мок в середине теста, это можно сделать с помощью метода page.unroute()
:
await page.unroute('https://*/**/users')
В Playwright вы можете имитировать любой HTTP-ответ, включая ошибки, такие как 403 Forbidden. Это полезно для тестирования, как ваше приложение будет вести себя при получении отказа в доступе от сервера.
import { test, expect } from '@playwright/test'
test('mock API with 403 response', async ({ page }) => {
// Создаём mock для ответа с кодом 403
await page.route('https://http.hexlet.app/js-playwright/users/', (route) => {
route.fulfill({
status: 403,
})
})
// Переходим на страницу, которая делает запрос на https://http.hexlet.app/js-playwright/users/
await page.goto('https://http.hexlet.app/js-playwright/users-list')
// Проверяем, что на странице отображается сообщение об ошибке доступа
const header = await page.getByRole('heading', { name: 'Доступ ограничен' })
await expect(header).toBeVisible()
})
Изменение ответа
Если вам нужно изменить ответ от реального сервера, а не просто замокировать его, в Playwright можно сначала позволить запросу пройти на сервер, а затем модифицировать полученный ответ перед тем, как он будет передан в приложение.
import { test, expect } from '@playwright/test'
test('mock API example', async ({ page }) => {
await page.route('*/**/users', (route) => {
// Ответ, который будет отправлен вместо реального запроса
const data = [
{ id: 1, firstName: 'Alice', lastName: 'Johnson', email: 'aliceJohnson@email.com' },
{ id: 2, firstName: 'Bob', lastName: 'Smith', email: 'bobsmith@email.com' },
]
const response = await route.fetch()
const json = await response.json()
json.push(...data)
// Оригинальный ответ передается как response
await route.fulfill({ response, json })
})
await page.goto('https://http.hexlet.app/js-playwright/users-list/')
const userNames = await page.getByRole('listitem').allTextContents()
await expect(userNames).toEqual(['Some Name From Server', 'Alice Johnson alicejohnson@email.com', 'Bob Smith bobsmith@email.com'])
})
Таким образом, этот подход позволяет вам работать с реальными данными, которые возвращает сервер, и при этом менять их по необходимости для тестирования различных сценариев.
Дополнительные материалы
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.