HTTP для тестировщика: методы, коды, headers, cookies и реальные проверки
HTTP без лишней теории для Manual QA: GET/POST/PUT/PATCH/DELETE, status codes, headers, cookies, idempotency и примеры API-проверок.
Manual QA может годами работать с вебом и при этом воспринимать HTTP как набор чисел: 200 хорошо, 404 плохо, 500 backend упал.
Для начала этого хватает. Для сильного тестирования — нет.
Когда понимаешь HTTP, DevTools перестаёт быть таблицей непонятных строк, Postman становится рабочим инструментом, а API-баги локализуются быстрее. И самое приятное: эта же база почти без изменений переезжает в REST Assured, когда ты переходишь к Java Automation.
Официальная спецификация HTTP огромная. QA не нужно учить её наизусть. Нужна небольшая модель, которая помогает задавать правильные вопросы продукту.
- Открыть учебный стенд ShawarmaShop
Реальный интерфейс приложения для практики UI и поиска запросов в DevTools.
- Открыть Swagger UI ShawarmaShop
Контракт API, endpoints, request body, schemas и responses.
Клиент отправляет request:
1POST /api/v1/orders HTTP/1.1
2Host: shawarma.threadqa.ru
3Content-Type: application/json
4Authorization: Bearer <token>
5
6{
7 "recipeId": 42,
8 "qty": 2,
9 "payment": { "method": "CARD" }
10}Сервер отвечает:
1HTTP/1.1 200 OK
2Content-Type: application/json
3
4{
5 "id": 7812,
6 "status": "PENDING",
7 "qty": 2,
8 "totalPrice": 890
9}Для QA здесь есть несколько независимых объектов проверки:
- ▸method;
- ▸URL;
- ▸headers;
- ▸body;
- ▸status code;
- ▸response headers;
- ▸response body;
- ▸побочный эффект в системе.
Если проверить только status code, большая часть поведения останется вне теста.
MDN описывает request method как указание того, какое действие клиент хочет выполнить над ресурсом. Самые нужные QA методы: GET, POST, PUT, PATCH и DELETE.
GET — получить
1GET /api/v1/orders/7812Обычно GET не должен менять состояние данных.
QA-проверки:
- ▸существующий ID;
- ▸несуществующий ID;
- ▸чужой ресурс;
- ▸удалённый ресурс;
- ▸query filters;
- ▸пагинация;
- ▸сортировка;
- ▸пустой результат.
Интересный дефект: GET-запрос неожиданно изменяет last_seen, счётчик или состояние сущности, хотя контракт этого не предполагает.
POST — создать или выполнить действие
1POST /api/v1/ordersPOST часто создаёт сущность или запускает операцию.
Проверяй:
- ▸валидные данные;
- ▸отсутствующие обязательные поля;
- ▸граничные значения;
- ▸неверные типы;
- ▸повторную отправку;
- ▸права доступа;
- ▸поведение при timeout/retry.
Последние два пункта особенно важны для платежей и заказов.
PUT — знать семантику, даже если endpoint'а сейчас нет
В текущей OpenAPI-спецификации ShawarmaShop PUT-операций нет. Но метод часто встречается в других API и обычно используется для полной замены представления ресурса. QA-вопрос остаётся тем же: что произойдёт с полем, которого нет в body? Ответ всегда ищем в контракте конкретного API.
PATCH — изменить часть
1PATCH /api/v1/recipes/42
2
3{
4 "price": 399
5}В ShawarmaShop UpdateRecipeRequest содержит опциональные name, description и price. Если меняешь только price, остальные поля рецепта не должны внезапно исчезнуть. Для этого endpoint контракт отдельно документирует 404 и 409.
DELETE — понимать, но не выдумывать его там, где его нет
В текущем ShawarmaShop DELETE endpoint'ов нет. Отмена заказа сделана отдельным бизнес-действием: POST /api/v1/orders/{id}/cancel. Это хороший пример, почему нельзя угадывать API только по названию операции — всегда смотри Swagger/OpenAPI.
MDN отдельно выделяет свойства методов: safe и idempotent.
Safe — запрос задуман как не меняющий состояние ресурса. GET считается safe.
Idempotent — повторение одного и того же запроса должно иметь тот же целевой эффект, что и один вызов. Особенно интересно, что POST сам по себе обычно не idempotent, но ShawarmaShop делает оплату безопасной для retry через обязательный Idempotency-Key.
Почему тестировщику это важно?
Потому что реальные системы делают retry.
Пользователь нажал «Оплатить». Интернет подвис. Клиент не получил ответ и повторил запрос.
В текущем контракте POST /api/v1/orders/{id}/pay требует header Idempotency-Key: повторный POST с тем же ключом должен вернуть уже созданный платёж и не ходить повторно к провайдеру.
Это уже не экзаменационный термин, а денежный баг.
Коды ответа группируются в пять классов:
- ▸1xx — информационные;
- ▸2xx — успешные;
- ▸3xx — redirect;
- ▸4xx — проблема с запросом клиента / доступом / ресурсом;
- ▸5xx — сервер не смог корректно обработать запрос.
Для ежедневной QA-работы полезно узнавать несколько кодов. В текущей спецификации ShawarmaShop явно документированы 200, 400, 401, 404, 409 и 502. Ниже есть и несколько общих кодов HTTP — они полезны как база, но не надо приписывать их конкретному endpoint, если их нет в его контракте.
200 OK
Операция успешна и обычно есть body.
Но 200 не гарантирует правильную бизнес-логику.
Плохой пример API:
1200 OK
2
3{
4 "success": false,
5 "error": "User not found"
6}Иногда это осознанный legacy-контракт, иногда — спорный дизайн. QA должен тестировать фактическую спецификацию, но расхождение стоит обсудить.
201 Created
Часто используется после создания ресурса в HTTP API вообще. Важно: текущий POST /api/v1/orders в ShawarmaShop документирует 200 OK, а не 201 Created.
Проверь, действительно ли сущность появилась и можно ли её затем получить.
204 No Content
Успешный ответ без body.
Если клиент пытается распарсить JSON из 204, можно получить frontend bug.
400 Bad Request
Некорректный запрос.
QA-вопросы:
- ▸ошибка понятна;
- ▸есть код ошибки;
- ▸поле ошибки указано;
- ▸не произошёл частичный side effect.
401 Unauthorized
Обычно нет корректной аутентификации.
Проверь запрос без token, с истёкшим token, битым token.
403 Forbidden
Пользователь распознан, но действие запрещено.
Классический тест ролей: обычный user пытается выполнить admin endpoint.
404 Not Found
Ресурс не найден.
Проверь случайный ID, удалённый ID, другой tenant, чувствительность к формату URL.
409 Conflict
Часто встречается при конфликте состояния: duplicate email, повторная операция, version conflict.
422 Unprocessable Content
Используется некоторыми API для семантически невалидных данных.
429 Too Many Requests
Rate limit.
Если продукт имеет публичный API или защиту от brute force, код стоит знать.
500 Internal Server Error
Самый важный вопрос: можем ли мы вместо 500 получить контролируемую 4xx ошибку на ожидаемо плохой пользовательский ввод?
Если qty = -1 приводит к stack trace и 500 — сервер явно обработал ожидаемо невалидный ввод хуже, чем мог. В CreateOrderRequest для qty задан minimum = 1.
HTTP headers позволяют клиенту и серверу передавать дополнительные метаданные.
Для QA начни с этих.
Content-Type
1Content-Type: application/jsonКакой формат body отправляем/получаем.
Тест:
- ▸отправь JSON с правильным Content-Type;
- ▸без Content-Type;
- ▸с неправильным text/plain;
- ▸проверь поведение API.
Accept
1Accept: application/jsonКакой формат клиент готов принять.
Authorization
1Authorization: Bearer <token>Проверь отсутствие, invalid/expired token и права.
Location
После создания ресурса API иногда возвращает ссылку на созданный ресурс.
Cache-Control
Важен при проблемах с кешированием и устаревшими данными.
Origin
Участвует в CORS-механике браузера.
Сервер может отправить:
1Set-Cookie: session=abc123; Secure; HttpOnly; SameSite=LaxБраузер затем отправляет cookie обратно.
MDN отдельно отмечает Secure, HttpOnly и SameSite как значимые атрибуты cookie.
Для Manual QA отсюда получаются практические сценарии:
- ▸cookie появилась после login;
- ▸исчезла/протухла после logout;
- ▸сессия действительно перестала работать;
- ▸разные пользователи не получают один session state;
- ▸remember-me соответствует требованиям;
- ▸приложение нормально ведёт себя после очистки cookies.
Посмотреть cookies удобно в Chrome DevTools → Application. Подробно: Chrome DevTools для тестировщика.
URL:
1/api/v1/ingredients?lowStock=trueЧто тестировать:
- ▸параметр отсутствует;
- ▸пустое значение;
- ▸неизвестное значение;
- ▸повторяющийся параметр;
- ▸очень большое page;
- ▸специальные символы;
- ▸кириллица;
- ▸пробелы;
- ▸URL encoding.
Фильтры выглядят безобидно, но часто дают много edge cases.
Ответ:
1{
2 "id": 7812,
3 "status": "PENDING",
4 "qty": 2,
5 "totalPrice": 890,
6 "payment": { "method": "CARD", "status": "PENDING" }
7}Если заказ создавался с qty = 2, а response вернул другое qty или неверный totalPrice — это дефект независимо от 200 OK.
Проверяй:
- ▸обязательные поля;
- ▸типы;
- ▸nullability;
- ▸значения enum;
- ▸вложенные объекты;
- ▸массивы;
- ▸business invariants.
Очень полезный принцип: Postman не браузер.
Браузер применяет security-механизмы, которых нет в обычном API-клиенте, в том числе CORS.
Поэтому сценарий:
в Postman endpoint работает, а frontend получает CORS error
вполне реален.
Смотри Network и Console, Origin и Access-Control-Allow-* headers. Не нужно сразу становиться специалистом по CORS, но важно понимать, почему «в Postman зелёное» не доказывает, что браузерный сценарий исправен.
Для каждого endpoint попробуй мыслить пятью слоями.
1. Transport
Пришёл ли ответ? Какой status? Время?
2. Contract
Правильная ли структура body, headers, типы?
3. Business
Правильные ли значения и переходы состояния?
4. Security/access
Кто может вызвать endpoint? Можно ли получить чужие данные?
5. Persistence/integration
Что произошло в БД, Kafka, внешней системе? В ShawarmaShop это можно проверить буквально: orders хранит lifecycle заказа, payments — попытки оплаты и idempotency_key, а event_log — read-модель доменных событий из Kafka.
Manual QA, который мыслит так, уже очень близок к тому, как строятся хорошие интеграционные автотесты.
Самое полезное упражнение:
- ▸1. открой любое web-приложение;
- ▸2. DevTools → Network → Fetch/XHR;
- ▸3. выполни действие;
- ▸4. найди request;
- ▸5. назови method;
- ▸6. найди status code;
- ▸7. посмотри headers;
- ▸8. посмотри payload;
- ▸9. посмотри response;
- ▸10. скопируй запрос в Postman.
Продолжение: Postman для тестировщика: REST API с нуля.
Если API документирован через Swagger/OpenAPI, следующий шаг — научиться читать контракт: Swagger/OpenAPI для тестировщика.
Вместо зубрёжки «что такое HTTP» потренируй объяснения на примерах:
- ▸чем POST отличается от PUT;
- ▸чем 401 отличается от 403;
- ▸что проверишь у POST /api/v1/orders;
- ▸что такое idempotency и почему важна для платежа;
- ▸что такое headers;
- ▸что такое cookie;
- ▸почему запрос работает в Postman и падает в браузере;
- ▸что будешь делать при 500;
- ▸как проверить API без UI.
Если можешь уверенно разобрать конкретный request/response — теории у тебя уже больше, чем кажется.
В Postman ты собираешь:
1method + URL + headers + bodyВ Java с REST Assured — буквально то же самое:
1given()
2 .header("Authorization", "Bearer " + token)
3 .contentType(ContentType.JSON)
4 .body(order)
5.when()
6 .post("/api/v1/orders")
7.then()
8 .statusCode(200)
9 .body("status", equalTo("PENDING"));Поэтому базовое понимание HTTP резко упрощает старт Automation. Ты уже знаешь предметную модель теста — остаётся научиться выразить её кодом.
В Java QA Automation ThreadQA HTTP и API не оторваны от реального проекта: REST Assured используется вместе с Java 21, PostgreSQL, Kafka, WireMock, Selenide и CI/CD на ShawarmaShop.
Если ты сейчас Manual QA, это не «смена профессии с нуля». Это следующий слой над теми же запросами, которые ты видишь каждый день в Network и Postman.
1GET получить
2POST создать / запустить действие
3PUT заменить
4PATCH изменить часть
5DELETE удалить
6
7200 OK
8201 Created
9204 No Content
10400 Bad Request
11401 Unauthorized
12403 Forbidden
13404 Not Found
14409 Conflict
15422 Unprocessable Content
16429 Too Many Requests
17500 Internal Server ErrorСохрани не как таблицу для зубрёжки, а как общий HTTP-справочник. Для конкретного ShawarmaShop endpoint ожидаемый код всегда бери из Swagger: например create order → 200, auth/me → 200/401, recipe patch → 200/404/409, reviews → 200/404/502.
- ▸Postman для тестировщика
- ▸Chrome DevTools для тестировщика
- ▸Swagger/OpenAPI для тестировщика
- ▸SQL для тестировщика
- ▸Java QA Automation ThreadQA
FAQ
Нужно ли Manual QA знать все HTTP status codes?
Нет. Понимай классы кодов и несколько самых частых. Остальное можно посмотреть в документации. Важнее уметь объяснить, какой ответ ожидаешь в конкретном сценарии.
Чем 401 отличается от 403?
Упрощённо: при 401 запрос не прошёл аутентификацию; при 403 сервер понял, кто ты, но действие не разрешено. Реальная реализация API может иметь особенности, поэтому сверяйся с контрактом.
POST всегда создаёт ресурс?
Нет. POST может запускать действие. Смысл определяется контрактом конкретного API.
Что такое idempotency простыми словами?
Повтор одного и того же запроса не должен давать дополнительный целевой эффект. Это особенно важно при retry платежей, заказов и других операций.
HTTP нужно учить до Postman?
Лучше параллельно. Несколько реальных запросов в Postman делают HTTP-термины намного понятнее.