Мокирование сети и API-тестирование
Updated Jul 2026
Playwright может перехватывать, модифицировать и мокировать сетевые запросы на уровне браузера — без прокси-сервера. Это позволяет тестировать пограничные случаи (ошибки сервера, медленные ответы, пустые состояния), которые сложно или невозможно воспроизвести с живым бэкендом, а также комбинировать UI-тесты с проверкой API в одном тесте.
Перехват запросов
page.route() перехватывает запросы, соответствующие шаблону URL, и позволяет выполнить, прервать или модифицировать их.
Мокирование API-ответов
test('показывает пустое состояние когда товаров нет', async ({ page }) => {
// Мокирование API для возврата пустого массива
await page.route('**/api/products', async (route) => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify([]),
});
});
await page.goto('/products');
await expect(page.getByText('Товары не найдены')).toBeVisible();
});
test('корректно обрабатывает ошибку сервера', async ({ page }) => {
await page.route('**/api/products', async (route) => {
await route.fulfill({ status: 500 });
});
await page.goto('/products');
await expect(page.getByRole('alert')).toHaveText(/что-то пошло не так/i);
});
Модификация запросов
// Добавление заголовка авторизации ко всем API-запросам
await page.route('**/api/**', async (route) => {
await route.continue({
headers: {
...route.request().headers(),
'Authorization': 'Bearer test-token',
},
});
});
// Модификация данных ответа (например, инъекция тестового флага)
await page.route('**/api/config', async (route) => {
const response = await route.fetch();
const json = await response.json();
json.featureFlags.newCheckout = true;
await route.fulfill({ response, body: JSON.stringify(json) });
});
Блокировка запросов
// Блокировка аналитики и трекинга в тестах
await page.route('**/{analytics,tracking}/**', (route) => route.abort());
// Блокировка изображений для ускорения тестов
await page.route('**/*.{png,jpg,jpeg,svg}', (route) => route.abort());
Ожидание сетевых событий
// Ожидание конкретного API-ответа после запуска действия
const responsePromise = page.waitForResponse('**/api/orders');
await page.getByRole('button', { name: 'Оформить заказ' }).click();
const response = await responsePromise;
expect(response.status()).toBe(201);
// Ожидание отправки запроса
const requestPromise = page.waitForRequest('**/api/search*');
await page.getByRole('searchbox').fill('ноутбук');
const request = await requestPromise;
expect(request.url()).toContain('q=ноутбук');
API-тестирование с фикстурой request
Фикстура request в Playwright выполняет прямые HTTP-вызовы без браузера — идеально для настройки, очистки и чистого API-тестирования.
test('API: создание и получение товара', async ({ request }) => {
// Создание
const createResponse = await request.post('/api/products', {
data: { name: 'Виджет', price: 9.99 },
});
expect(createResponse.status()).toBe(201);
const product = await createResponse.json();
// Получение
const getResponse = await request.get(`/api/products/${product.id}`);
expect(getResponse.status()).toBe(200);
const retrieved = await getResponse.json();
expect(retrieved.name).toBe('Виджет');
});
Комбинирование UI + API-тестов
Наиболее мощный паттерн: используйте API для подготовки данных, проверяйте через UI, затем валидируйте через API.
test('пользователь может обновить профиль', async ({ page, request }) => {
// Подготовка: создание пользователя через API
await request.post('/api/users', {
data: { name: 'Алиса', email: 'alice@test.com' },
});
// UI: обновление профиля
await page.goto('/profile');
await page.getByLabel('Имя').fill('Алиса Смирнова');
await page.getByRole('button', { name: 'Сохранить' }).click();
await expect(page.getByRole('alert')).toHaveText('Профиль обновлён');
// Проверка: убедиться через API, что изменение сохранилось
const response = await request.get('/api/users/alice');
const user = await response.json();
expect(user.name).toBe('Алиса Смирнова');
});
Паттерны мокирования сети
| Паттерн | Сценарий использования |
|---|---|
| Полный мок | Тестирование UI в изоляции от бэкенда |
| Симуляция ошибок | Проверка обработки ошибок (500, 403, таймаут) |
| Медленный ответ | Тестирование состояний загрузки и спиннеров |
| Модифицированный ответ | Инъекция feature-флагов или тест-специфичных данных |
| Блокировка запросов | Блокировка аналитики, изображений, сторонних скриптов |
| Запись и воспроизведение | Снимки реальных ответов для детерминированных тестов |
Симуляция медленных ответов
test('показывает спиннер загрузки при медленном API', async ({ page }) => {
await page.route('**/api/reports', async (route) => {
await new Promise((resolve) => setTimeout(resolve, 3000));
await route.fulfill({ status: 200, body: '[]' });
});
await page.goto('/reports');
await expect(page.getByTestId('spinner')).toBeVisible();
await expect(page.getByTestId('spinner')).not.toBeVisible({ timeout: 5000 });
});
Ключевые выводы
page.route()перехватывает запросы на уровне браузера — прокси-сервер не нужен- Мокируйте API для тестирования пограничных случаев: пустые состояния, ошибки, медленные ответы, feature-флаги
- Используйте фикстуру
requestдля прямых API-вызовов — быстрее, чем UI для подготовки и проверки - Комбинируйте UI + API-тестирование: подготовка через API, взаимодействие через UI, проверка через API
- Блокируйте аналитику и ненужные ресурсы для ускорения выполнения тестов