← назад к разделу

Когда вы нажимаете «Войти» или открываете список заказов, страница не хранит эти данные у себя — она спрашивает сервер. Этот обмен «вопрос — ответ» лежит в основе почти всех приложений, и тестировщику важно понимать, где в нём что ломается.

Разберём, из чего состоят запрос и ответ и что означают коды, которыми сервер отвечает. Это фундамент, на котором стоят DevTools и тестирование API.

Клиент и сервер

Клиент — это то, чем пользуется человек: браузер, мобильное приложение. Он показывает интерфейс и отправляет запросы. Сервер — компьютер где-то в дата-центре, который хранит данные (пользователей, заказы) и отвечает на запросы клиента.

Аналогия: клиент — посетитель в кафе, сервер — кухня. Посетитель делает заказ (запрос), кухня готовит и отдаёт блюдо (ответ); на кухню он не заходит.

Почему это важно тестировщику: баг может быть на клиенте (страница отправила не то или не так показала ответ) или на сервере (обработал неверно, вернул ошибку). Понимая разделение, вы точнее пишете баг-репорт.

HTTP и HTTPS

HTTP (HyperText Transfer Protocol) — это язык, на котором клиент и сервер договариваются: как оформить запрос, как — ответ. Каждый раз, когда страница что-то грузит или отправляет, происходит HTTP-обмен.

HTTPS — то же самое, но зашифрованное (буква S — secure): по дороге запрос не перехватить и не прочитать. Сегодня нормальный сайт всегда работает по HTTPS; если сайт на обычном HTTP, браузер помечает его как «небезопасный». Это тоже предмет проверки — что важные страницы (оплата, вход) идут по HTTPS.

Прячется при этом не всё. Зашифрованы тело запроса и ответа, заголовки и путь: /api/orders/17?token=abc снаружи не виден. А вот домен виден: провайдер и владелец Wi-Fi знают, что вы ходили на example.com, но не знают, что вы там делали. Прятать секрет в параметрах адреса поэтому бесполезно — он осядет в логах сервера и в истории браузера.

На стенде HTTPS обычно поднят самоподписанным сертификатом — тем, который никто не заверял. Браузер на него ругается, и для стенда это нормально, а не баг; баг — то же предупреждение на проде, чаще всего из-за истёкшего сертификата. Заодно поэтому запрос со стенда не уходит из Postman или с телефона: клиент не доверяет сертификату.

Запрос: из чего состоит

Запрос состоит из четырёх частей:

  • Метод — что мы хотим сделать. Основные: GET (получить данные — «покажи заказы»), POST (создать — «оформи заказ»), PUT/PATCH (изменить), DELETE (удалить).
  • URL (адрес) — куда обращаемся, например example.com/api/orders.
  • Заголовки (headers) — служебная информация: формат данных, токен, язык.
  • Тело (body) — сами данные, чаще всего в формате JSON и чаще всего у POST.

Слово CRUD (создать — прочитать — изменить — удалить) означает ровно эти методы: POST, GET, PUT или PATCH, DELETE.

JSON — простой текстовый формат «ключ: значение», которым обмениваются клиент и сервер:

{ "email": "anna@example.com", "amount": 1500 }

Ответ: из чего состоит

В ответе тестировщику важны две вещи:

  • Статус-код — короткий итог запроса числом: 2xx успех, 3xx другой адрес, 4xx виноват запрос, 5xx сломался сервер.
  • Тело ответа — сами данные (обычно JSON): список заказов, созданный объект, сообщение об ошибке.

Статус-коды: какой когда

Точный номер говорит, что именно чинить, и в баг-репорте весит больше слов. Проверяем не «пришёл ли 200», а «верный ли здесь код»: сервер, отвечающий 200 на несуществующий заказ, обманывает и клиента, и вас.

  • 200, 201 и 204. 200 — «вот данные». 201 — «создал»: ответ на POST, адрес нового объекта обычно в заголовке Location. 204 — «сделал, показывать нечего»: обычный ответ на DELETE, тело пустое, и падение клиента на разборе пустого тела — дефект клиента.
  • 301 против 302. 301 — переезд навсегда, браузер запомнит новый адрес надолго: ошибочный 301 на стенде преследует до очистки кэша. 302 — временно, главным остаётся старый адрес; временную заглушку отдают именно им.
  • 400 против 422. 400 — запрос не разобрали: сломанный JSON, не тот тип, нет обязательного поля. 422 — разобрали, но данные спорят с правилами: дата в прошлом, сумма больше остатка. 400 чинит клиент, 422 — бизнес-правило, и в ответе должно быть сказано, какое поле не так.
  • 401 против 403. 401 — «не понял, кто ты»: токена нет или он истёк. 403 — «понял, но тебе нельзя». Разбор — во входе в систему.
  • 404 против 409. 404 — объекта нет. 409 — конфликт: объект есть, но действие спорит с его состоянием: занятый e-mail при регистрации, отмена уже отменённого заказа. 404 вместо 409 — частая подмена: человек читает «не найдено» там, где на самом деле «уже занято».
  • 429. Слишком часто — сработало ограничение частоты. Ловится повторной отправкой кода из СМС: ждём заголовок Retry-After и понятный текст, а не пустой экран.
  • 500 против 502 и 504. 500 пишет само приложение — упало внутри. 502 и 504 приходят от посредника между вами и приложением: «тот, кто должен ответить, не ответил» и «не дождался». Чинить это будут разные люди — подробнее в основах сетей.

Повтор запроса: что безопасно, а что нет

Кнопку «Оплатить» нажимают дважды, связь рвётся на середине, мобильный клиент сам повторяет запрос. Вопрос не «бывает ли такое», а «что будет».

один и тот же запрос ушёл дважды: палец дрогнул, связь моргнула POST /orders «создай ещё один» сервер попытка 1заказ #17 создан попытка 2заказ #18 создан — второй PUT /orders/17 «пусть будет так» сервер попытка 1#17: оплачен попытка 2#17: оплачен — то же самое GET, PUT и DELETE можно повторять; POST — только с ключом идемпотентности

Два одинаковых POST дают два заказа: адрес новому объекту назначает сервер, и он честно создаёт второй. Два одинаковых PUT дают один и тот же итог: адрес известен, второй запрос просто перезаписывает теми же значениями. Поэтому двойной клик проверяют на POST, а не на PUT.

У методов есть два свойства. Безопасный — не меняет данные на сервере: GET можно дёргать сколько угодно. Идемпотентный — повтор не меняет итог: сколько раз ни отправь, состояние одно. GET, PUT и DELETE идемпотентны, POST — нет.

Причина в смысле методов. PUT говорит «пусть будет так» и знает адрес объекта: второй такой же PUT перезапишет теми же значениями. DELETE — «пусть этого не будет»: во второй раз удалять нечего, и пусть код придёт 404, состояние прежнее. POST говорит «создай ещё один», и адрес новому объекту назначает сервер — второй POST честно создаёт второй заказ.

Проверок отсюда три: двойной клик по «Отправить» — один заказ или два (смотреть в данных, а не на экране); повторная отправка того же запроса из Network или Postman; ключ идемпотентности — на платежах клиент шлёт заголовок вроде Idempotency-Key, и по тому же ключу сервер обязан вернуть результат первой попытки, а не провести второй платёж: два запроса с одним ключом — один платёж, с разными — два.

Заголовки, которые стоит смотреть

Заголовки многие пролистывают — и зря: они решают, как сервер поймёт запрос и что браузер сделает с ответом.

Content-Type объявляет формат тела: application/json для JSON, multipart/form-data для загрузки файлов. Ошибка здесь выглядит странно — тело правильное, а в ответе 400 или 415: сервер не стал разбирать то, что ему объявили не тем форматом. Authorization — кто спрашивает, обычно Bearer и токен; нет заголовка — 401, разбор во входе в систему. Cache-Control говорит, сколько ответ разрешено держать в кэше, и из-за него страница показывает вчерашние данные, хотя сервер отдаёт новые.

Где это применяется

Эта модель — под каждым действием в приложении. Форма «молча» не сохранилась — открываете вкладку Network: запрос ушёл? какой метод и код в ответе? 500 — сервер, запрос не ушёл вовсе — клиент. Перебирать варианты запроса руками удобно в Postman.

Где спотыкаются начинающие:

  • Проверяют только «пришёл ли 200». Код обязан быть верным по смыслу: 200 на несуществующий заказ — дефект, даже когда экран выглядит прилично.
  • Считают повтор запроса теорией. Двойной клик по «Оплатить» обычен, и второй платёж после него — дефект.

Что учить дальше. Обмен смотрят в DevTools, проверяют запросы руками в Postman, а что происходит ниже HTTP — в основах сетей.