Когда UI показывает неправильные данные, вкладка Network в DevTools говорит тебе: API вернул неправильные данные (баг бэкенда) или правильные данные отобразились некорректно (баг фронтенда). Для этой диагностики нужно понимать как устроены REST-запросы и ответы. Статья разбирает HTTP-методы, статус-коды (включая почему успешный POST должен возвращать 201, а не 200), заголовки аутентификации и как делать прямые API-вызовы в Playwright-тестах.
Базовая концепция: запрос и ответ
API (Application Programming Interface): способ для двух программ общаться между собой. REST API: конкретный стиль API который использует HTTP, тот же протокол которым браузер загружает сайты.
Разговор всегда строится одинаково: твой код (или тест) отправляет запрос, а сервер обрабатывает его и отправляет обратно ответ.
Всё. Остальное: детали того как эти две вещи устроены.
Анатомия HTTP-запроса
Каждый запрос состоит из четырёх частей.
1. Метод (глагол)
Метод говорит серверу что ты хочешь сделать:
| Метод | Что делает | Как сказать |
|--------|-------------|-------------|
| GET | Получить данные | «Дай мне это» |
| POST | Создать что-то новое | «Вот новые данные, сохрани» |
| PUT | Заменить целиком | «Замени это на мою новую версию» |
| PATCH | Обновить часть | «Измени только это поле» |
| DELETE | Удалить | «Удали это» |
Эндпоинт баг-трекера может работать так:
GET /bugs: список всех баговGET /bugs/42: баг №42POST /bugs: создать новый багPATCH /bugs/42: обновить статус бага №42DELETE /bugs/42: удалить баг №42
2. URL (адрес)
URL говорит серверу с чем ты работаешь:
https://api.becomeqa.com/v1/users/123/ordersРазбивка:
https://api.becomeqa.com: сервер/v1: версия API (частое, но не обязательное)/users/123: конкретный пользователь с ID 123/orders: его заказы
Части после домена называются путём (path). Числа и ID в пути (как 123) называются path-параметрами.
Иногда данные передаются в URL как query-параметры:
GET /users?role=admin&active=true&page=2Часть ?role=admin&active=true&page=2 фильтрует и пагинирует результаты, не меняя о каком ресурсе идёт речь.
3. Заголовки
Заголовки: метаданные которые отправляются с запросом. В браузере они не видны напрямую, только во вкладке Network. Распространённые:
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Accept: application/jsonContent-Type указывает в каком формате тело запроса, Authorization подтверждает личность (подробнее ниже), а Accept сообщает в каком формате хочешь получить ответ.
4. Тело
Запросы POST, PUT и PATCH обычно включают тело: реальные отправляемые данные. REST API почти всегда используют JSON:
{
"title": "Кнопка логина не работает на мобильном",
"severity": "high",
"steps": ["Открыть приложение на мобильном", "Нажать Login", "Ничего не происходит"]
}Запросы GET и DELETE обычно без тела.
Анатомия HTTP-ответа
Сервер отвечает тремя частями.
1. Статус-код
Трёхзначное число, которое говорит что произошло:
| Диапазон | Категория | Значение |
|-------|----------|---------|
| 2xx | Успех | Запрос выполнен |
| 3xx | Редирект | Ресурс переехал, иди сюда |
| 4xx | Ошибка клиента | Твой запрос неверен |
| 5xx | Ошибка сервера | Сервер сломался |
Самые важные коды для тестирования:
| Код | Название | Когда появляется |
|------|------|----------------|
| 200 | OK | Стандартный успех для GET |
| 201 | Created | POST, который создал что-то |
| 204 | No Content | Успех, но нечего возвращать (DELETE) |
| 400 | Bad Request | Невалидный ввод (отсутствует поле, неверный формат) |
| 401 | Unauthorized | Не аутентифицирован (нет/плохой токен) |
| 403 | Forbidden | Аутентифицирован, но не разрешено |
| 404 | Not Found | Ресурс не существует |
| 422 | Unprocessable Entity | JSON валидный, но не проходит бизнес-валидацию |
| 429 | Too Many Requests | Превышен лимит запросов |
| 500 | Internal Server Error | Необработанный краш бэкенда |
| 503 | Service Unavailable | Сервер недоступен или перегружен |
2. Заголовки ответа
Аналогично заголовкам запроса: метаданные об ответе.
Content-Type: application/json
X-Request-Id: abc-123-def
Cache-Control: no-cache3. Тело ответа
Реальные возвращаемые данные, обычно JSON:
{
"id": 42,
"title": "Кнопка логина не работает на мобильном",
"severity": "high",
"status": "open",
"created_at": "2026-05-17T10:30:00Z"
}Или ошибка:
{
"error": "validation_failed",
"message": "Title is required",
"field": "title"
}Аутентификация: как API знает кто ты
Большинство API требуют аутентификации. Два основных подхода которые ты встретишь.
Bearer Token / JWT
После логина сервер выдаёт токен: длинную строку которая подтверждает личность. Ты включаешь его в каждый последующий запрос:
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjEyMywicm9sZSI6ImFkbWluIn0.abc123Сервер валидирует токен без обращения к базе данных для поиска сессии. Токены истекают (обычно от 15 минут до 24 часов).
Cookie-based сессии
Более старый паттерн. После логина сервер устанавливает куку. Браузер автоматически отправляет её с каждым запросом к этому домену. Ты не видишь её в теле запроса, браузер управляет этим сам.
API-ключи
Используются для межсерверного взаимодействия. Статический ключ в заголовке:
X-API-Key: sk-1234567890abcdefКак инспектировать API-вызовы в браузере
Открой DevTools, перейди на вкладку Network, отфильтруй по «Fetch/XHR». Все API-вызовы которые делает приложение появятся здесь.
Кликни на любой запрос чтобы увидеть:
- Вкладка Headers: заголовки запроса, URL, метод
- Вкладка Payload: тело запроса
- Вкладка Response: что вернул сервер
- Статус-код: в виде списка, колонка с числом
Здесь диагностируешь «это баг фронтенда или бэкенда?». Если UI показывает неправильные данные, проверь что API реально вернул. Если API вернул правильные данные, а UI показывает их неправильно, это фронтенд. Если API вернул неправильные данные, это бэкенд.
Тестирование API: что проверять
При тестировании API-эндпоинта (вручную или в Playwright) верифицируй следующее.
Статус-код соответствует ожиданию
- Создание ресурса:
201, не200 - Получение ресурса:
200 - Успешное удаление без тела:
204 - Невалидный ввод:
400или422, не500
Тело ответа корректно
- Обязательные поля присутствуют
- Типы данных правильные (
"age": 25, не"age": "25") - Значения совпадают с отправленными
- Чувствительные данные не утекают (пароли, внутренние ID)
Ошибочные ответы информативны
Ошибки 400 должны объяснять что невалидно. Ошибки 404 должны подтверждать что ресурс не существует. Ошибки 401 не должны раскрывать security-чувствительную информацию.
Граничные случаи ведут себя корректно
- Пустой список: возвращает
[], неnull - Несуществующий ID: возвращает
404, не500 - Невалидный JSON в теле: возвращает
400, не500 - Неавторизованное действие: возвращает
403, не200с пустым телом
REST API в Playwright
Playwright умеет делать HTTP-запросы напрямую, без браузера:
test('создание пользователя возвращает 201', async ({ request }) => {
const response = await request.post('https://api.becomeqa.com/users', {
data: {
name: 'Test User',
email: 'test@example.com',
role: 'member',
},
});
expect(response.status()).toBe(201);
const body = await response.json();
expect(body.id).toBeTruthy();
expect(body.email).toBe('test@example.com');
expect(body).not.toHaveProperty('password'); // проверяем что пароль не утекает
});Можно также перехватывать API-вызовы которые делает браузер во время E2E-тестов:
test('приложение корректно обрабатывает ошибку API', async ({ page }) => {
// Принудительно возвращаем ошибку от API
await page.route('**/api/users', (route) => {
route.fulfill({ status: 500, body: JSON.stringify({ error: 'server error' }) });
});
await page.goto('/users');
// Приложение должно показать состояние ошибки, не упасть
await expect(page.locator('[data-testid="error-banner"]')).toBeVisible();
});Словарь ключевых терминов
| Термин | Значение |
|------|---------|
| API | Интерфейс для взаимодействия программ |
| REST | Стиль API который использует HTTP |
| Эндпоинт | Конкретная комбинация URL + метод (GET /users) |
| Запрос | То что отправляешь серверу |
| Ответ | То что сервер отправляет обратно |
| Статус-код | Трёхзначное число, успех или ошибка |
| JSON | Формат данных для REST API (текст, пары ключ-значение) |
| Заголовок | Метаданные прикреплённые к запросу или ответу |
| Тело | Реальные данные в запросе или ответе |
| Bearer token | Учётные данные в заголовке Authorization |
| Path-параметр | Переменная часть URL (/users/123, где 123 выступает параметром) |
| Query-параметр | Фильтры в URL после ? (?page=2&sort=asc) |
Понимание REST API делает тебя значительно сильнее как QA-инженера. Читаешь сетевой трафик, диагностируешь где баг: на фронтенде или бэкенде, пишешь API-тесты которые работают в 100 раз быстрее браузерных, и ведёшь намного более предметные разговоры с разработчиками при заведении багов.
→ See also: API-тестирование 101: всё, что нужно знать QA-инженеру в 2026 году | HTTP статус-коды, которые должен знать каждый QA-инженер | API-тестирование в Playwright: выходим за рамки UI | Как работает интернет: объяснение для тестировщиков