Мокирование API ответов

Одной из распространённых задач при автоматизированном тестировании является работа с API. Однако, в реальных условиях тестирования не всегда возможно подключиться к настоящему серверу. В таких случаях важным инструментом становится мокирование (замещение) API-ответов. Это позволяет имитировать работу серверов, контролировать тестируемые данные и повышать стабильность тестов. В Playwright этот процесс организуется с помощью функций, позволяющих перехватывать запросы и отвечать на них заданными данными.

Подходы к мокированию

Мокирование в Playwright осуществляется через перехват HTTP-запросов, что позволяет заменить реальные ответы на заранее подготовленные. Это нужно для того, чтобы тесты не зависели от состояния внешних сервисов и сетевых задержек.

В Playwright мокирование может быть реализовано с помощью метода page.route(). Этот метод позволяет захватывать сетевые запросы и изменять их поведение, предоставляя полную гибкость в создании фиктивных ответов.

Основные методы для мокирования

page.route()

Метод page.route() используется для перехвата запросов на определённые URL и замены ответов. Он принимает два параметра:

  • URL или регулярное выражение для фильтрации запросов. Это может быть строка, содержащая часть пути запроса, или регулярное выражение, которое будет соответствовать нескольким запросам.
  • Обработчик (handler). Это функция, которая принимает запрос и может модифицировать ответ.

Пример мокирования API-запроса:

await page.route('**/api/data', async (route, request) => {
    const response = {
        status: 200,
        body: JSON.stringify({ message: 'Mocked Response' }),
        contentType: 'application/json'
    };
    await route.fulfill(response);
});

В этом примере все запросы к URL, содержащему api/data, будут заменены на фиксированный ответ с кодом 200 и телом, содержащим строку "Mocked Response".

route.fulfill()

Метод route.fulfill() используется для имитации успешного ответа от сервера. Он принимает объект, который может включать:

  • status. HTTP-статус ответа (например, 200, 404).
  • body. Тело ответа, которое может быть строкой или буфером.
  • headers. Дополнительные заголовки, если нужно.
  • contentType. Тип контента (например, application/json).

Пример с использованием заголовков:

await page.route('**/api/data', async (route, request) => {
    await route.fulfill({
        status: 200,
        body: JSON.stringify({ data: 'Example data' }),
        headers: {
            'Content-Type': 'application/json',
            'Cache-Control': 'no-store'
        }
    });
});

route.abort()

Метод route.abort() позволяет отменить запрос, если необходимо имитировать ошибку сервера или сеть, недоступную по каким-то причинам.

Пример использования:

await page.route('**/api/data', async (route, request) => {
    await route.abort();
});

В этом случае запрос к api/data будет полностью отменён, и клиент получит ошибку, как если бы сеть была недоступна.

Ручное управление запросами

Иногда необходимо не просто мокировать запросы, но и реагировать на них в зависимости от данных, которые они содержат. В Playwright можно анализировать запросы и давать различные ответы на основе данных в запросе.

Пример:

await page.route('**/api/users', async (route, request) => {
    const postData = JSON.parse(request.postData());
    if (postData.username === 'admin') {
        await route.fulfill({
            status: 200,
            body: JSON.stringify({ message: 'Welcome Admin' })
        });
    } else {
        await route.fulfill({
            status: 200,
            body: JSON.stringify({ message: 'Welcome User' })
        });
    }
});

В данном примере запросы с разными данными будут приводить к разным ответам. Если в запросе указано имя пользователя “admin”, возвращается одно сообщение, для всех остальных пользователей — другое.

Использование моков с внешними API

Мокирование полезно, когда тесты зависят от внешних сервисов, которые могут быть нестабильными или недоступными. Вместо того чтобы обращаться к реальному API, можно заменить запросы и работать с заранее подготовленными данными.

Пример мокирования ответа от внешнего API:

await page.route('https://jsonplaceholder.typicode.com/todos/1', async (route, request) => {
    await route.fulfill({
        status: 200,
        body: JSON.stringify({ userId: 1, id: 1, title: 'Test task', completed: false }),
        contentType: 'application/json'
    });
});

В этом примере происходит замена ответа от публичного API на заранее подготовленный, что позволяет ускорить тесты и избавиться от зависимости от реального сервера.

Мокирование с использованием фальшивых данных

Для мокирования с фальшивыми данными можно использовать библиотеки вроде faker.js или chance.js. Это позволяет генерировать случайные данные для различных полей, что делает тестирование более разнообразным.

Пример с использованием faker.js:

const faker = require('faker');

await page.route('**/api/user', async (route, request) => {
    const fakeUser = {
        name: faker.name.findName(),
        email: faker.internet.email(),
        address: faker.address.streetAddress()
    };

    await route.fulfill({
        status: 200,
        body: JSON.stringify(fakeUser),
        contentType: 'application/json'
    });
});

Тестирование на нескольких сценариях

Часто тесты требуют мокирования для различных сценариев, включая успешные ответы, ошибки или тайм-ауты. Playwright позволяет легко управлять различными ситуациями и использовать их для проверки поведения приложения.

Пример:

await page.route('**/api/authenticate', async (route, request) => {
    const token = request.headers()['authorization'];
    if (token === 'valid_token') {
        await route.fulfill({
            status: 200,
            body: JSON.stringify({ success: true }),
            contentType: 'application/json'
        });
    } else {
        await route.fulfill({
            status: 401,
            body: JSON.stringify({ error: 'Unauthorized' }),
            contentType: 'application/json'
        });
    }
});

Этот пример показывает, как мокировать ответ в зависимости от данных, переданных в заголовке запроса (например, токен для авторизации).

Заключение

Мокирование API-ответов в Playwright позволяет улучшить стабильность и предсказуемость автоматизированных тестов, делая их независимыми от внешних сервисов и сетевых условий. Использование page.route(), методов route.fulfill() и route.abort() даёт полный контроль над запросами и ответами, а возможность генерировать динамичные данные позволяет тестировать различные сценарии.