ТестированиеТестирование API и интеграцийИнженер по интеграционному тестированию

Представьте: клиент объявляет поддержку сжатия, а сервер возвращает сжатое тело без корректного Content Enc...

Представьте: клиент объявляет поддержку сжатия, а сервер возвращает сжатое тело без корректного Content-Encoding. Какой интеграционный контракт должен проверять тест?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Тест должен проверять согласованность заголовков Accept-Encoding и Content-Encoding с фактическим представлением тела. Если тело сжато, сервер обязан явно указать применённый алгоритм в Content-Encoding; иначе клиент может попытаться разобрать сжатые байты как обычный текст и завершить обработку ошибкой.

Исторический контекст

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

Такое согласование разделяет две задачи: Content-Type описывает формат данных, например JSON, а Content-Encoding описывает преобразование этих данных при передаче, например сжатие. Клиент сначала должен учесть кодирование, а затем интерпретировать полученное содержимое.

Постановка проблемы

Проверка только HTTP-статуса и структуры распакованного тела не обнаружит ошибку, если тестовый клиент автоматически распаковывает ответ или библиотека сама компенсирует отсутствующий заголовок. В реальном клиенте такой ответ может привести к ошибке декодирования, повреждённым данным или неверной диагностике формата.

Особенно опасен непоследовательный дефект: сервер корректно формирует заголовки для одних ответов, но теряет Content-Encoding при прохождении через прокси, кэш или отдельный обработчик ошибок. Тогда обычные интеграционные проверки проходят, а сбой проявляется только на крупных или редко используемых ответах.

Подробное решение

Интеграционная проверка должна отправить запрос с явно заявленной поддержкой сжатия и проверить три связанных свойства:

  • сервер выбрал только алгоритм, заявленный клиентом;
  • заголовок Content-Encoding присутствует, если тело действительно сжато;
  • после обработки указанного кодирования тело соответствует ожидаемому формату и содержимому.

Важно проверять не только наличие заголовка, но и его соответствие байтам ответа. Заголовок, объявляющий сжатие, при несжатом теле тоже является дефектом: клиент попытается выполнить лишнее преобразование. Если клиент не заявляет поддержку конкретного алгоритма, сервер не должен применять его в ответе.

Content-Encoding не заменяет Content-Type. Например, ответ может иметь тип application/json и одновременно быть передан с кодированием сжатия. Тест должен сначала проверить корректность транспортного кодирования, а затем обычный контракт JSON.

Автоматическая распаковка удобна для большинства тестов, но скрывает часть ошибок. Поэтому полезно иметь отдельную проверку на уровне необработанных заголовков и тела либо отключать автоматическую распаковку в этом сценарии. Это увеличивает связанность теста с HTTP-клиентом, зато позволяет проверить именно сетевой контракт.

Ситуация из практики

Сервис отдавал отчёты в JSON. Для больших ответов промежуточный прокси сжимал тело, но в одном маршруте удалял Content-Encoding. Обычный тест проходил, потому что клиентская библиотека автоматически распаковывала ответ, а небольшой ответ прокси не сжимал.

Рассматривались два варианта. Проверять только размер ответа было недостаточно: размер зависит от данных и не доказывает корректность заголовков. Проверять только успешную десериализацию также оказалось ненадёжно, поскольку библиотека скрывала транспортную ошибку.

Выбрали отдельный интеграционный сценарий с крупным фиксированным набором данных и отключённой автоматической распаковкой. Тест проверял согласованность Content-Encoding с необработанным телом, после чего отдельно распаковывал его и проверял JSON. Дефект обнаружили до выпуска; дополнительным компромиссом стала необходимость учитывать настройки конкретного HTTP-клиента в тестовой инфраструктуре.

Что кандидаты часто упускают

  1. Достаточно ли проверить только заголовок Content-Encoding?

Нет. Заголовок может присутствовать при фактически несжатом теле или содержать алгоритм, отличный от применённого. Надёжная проверка сопоставляет заголовок с необработанными байтами и подтверждает, что после декодирования получается ожидаемое содержимое.

  1. Как отличить ошибку сжатия от ошибки формата JSON?

Нужно разделить этапы проверки. Сначала проверяется транспортный уровень: выбранное кодирование разрешено запросом, заголовки согласованы, тело корректно декодируется. Затем проверяется Content-Type и структура JSON. Иначе ошибка распаковки может ошибочно выглядеть как нарушение схемы данных.

  1. Нужно ли проверять отсутствие Content-Encoding для каждого несжатого ответа?

Не обязательно проверять это для всех сценариев, но должен существовать сценарий, где ответ гарантированно не кодируется, например из-за отсутствия поддержки сжатия в запросе. Такой тест выявит сервер, который применяет алгоритм без согласования или оставляет устаревший заголовок. Проверка особенно полезна на границах прокси и кэшей, где заголовки и тело могут обрабатываться разными компонентами.