Клиент повторяет запрос после любого неуспешного HTTP-ответа. Какой дефект интеграционный тест должен выявить для постоянной ошибки валидации?
Интеграционный тест должен подтвердить, что постоянная ошибка валидации, например ответ 400, не приводит к автоматическим повторам запроса. Повторять следует только ошибки, которые классифицированы как временные или явно допускают повтор; иначе возрастает нагрузка, а неидемпотентная операция может выполнить побочный эффект несколько раз.
Повторы появились как средство борьбы с временными сбоями сети, перегрузкой и кратковременной недоступностью зависимостей. Однако без классификации ошибок механизм повтора начинает трактовать любую неудачу как временную, хотя многие ошибки вызваны самим запросом и не исчезнут от повторной отправки.
Ошибка валидации означает, что сервер не может корректно обработать текущие входные данные. Повторение такого же запроса обычно приводит к тому же результату, создаёт лишний трафик и может замаскировать исходную ошибку.
Особенно опасен повтор для операций с побочными эффектами. Если сервер успел изменить состояние, но клиент получил ошибочный или неоднозначный ответ, без отдельного контракта идемпотентности повтор может создать дубликат записи, платежа или сообщения.
Тест должен отправить запрос с заведомо некорректными данными через тот же клиентский механизм, который используется приложением, и проверить несколько свойств: сохраняется исходный ответ об ошибке, количество обращений к серверу равно одному, а состояние системы не изменилось частично.
Классификация должна быть основана не только на статусе HTTP. Обычно ответы класса 4xx, связанные с синтаксисом и бизнес-валидацией, не повторяют, а временные сбои, такие как перегрузка или временная недоступность, могут повторяться по правилам API. Исключения возможны, поэтому интеграционный тест должен опираться на конкретный контракт сервиса: код ошибки, признак временности или иной формальный сигнал.
Проверка количества запросов требует наблюдаемого сервера, журнала обращений или счётчика на тестовой зависимости. Проверять только финальный ответ недостаточно: клиент может несколько раз отправить запрос, а затем вернуть тот же результат.
У повтора есть компромисс: слишком строгая политика пропустит временный сбой, а слишком широкая создаст лишние операции. Поэтому правила должны учитывать тип ошибки, безопасность метода, тайм-ауты и наличие механизма идемпотентности; сам тест на постоянную валидационную ошибку защищает именно от безусловного повтора.
Сервис заказов возвращал ошибку валидации, если промокод не соответствовал региону клиента. HTTP-клиент повторял все неуспешные ответы три раза, поэтому один ошибочный заказ вызывал четыре одинаковых обращения и перегружал сервис проверки промокодов.
Рассматривались два варианта. Полностью отключить повторы было безопасно для данных, но ухудшило бы устойчивость к временным сбоям. Ограничить повторы только временными ошибками было сложнее, зато сохранило восстановление после кратковременной недоступности и исключило повторы для ошибок валидации.
Выбрали второй вариант: контракт ошибки содержал признак временности, а интеграционные проверки отдельно подтверждали один запрос для постоянной ошибки и ограниченное число повторов для временной. В результате тест выявлял регрессии в политике повторов до выпуска, а исправление снизило лишнюю нагрузку без отказа от устойчивости.
Нет. Такой тест не показывает, сколько раз запрос фактически ушёл на сервер. Нужно наблюдать число обращений или эффект на тестовой зависимости; иначе несколько повторов останутся незамеченными.
Нет. Большинство ошибок запроса действительно не исправляются повтором тех же данных, но конкретный API может определить временный случай среди ответов 4xx. Поэтому решение должно опираться на контракт ошибки, а не на механическое правило по классу статуса.
Потому что тайм-аут не сообщает, обработал ли сервер запрос. Сервер мог успешно выполнить операцию, а ответ потерялся по пути. Для такого случая нужны отдельные гарантии: идемпотентный контракт операции, ключ идемпотентности или способ безопасно проверить результат; классификация ошибки валидации решает другую задачу — предотвращает повтор заведомо некорректного запроса.