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

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

Событие публикуется независимо от версии потребителя: продюсер добавил обязательное поле, после чего старый потребитель перестал его обрабатывать. Какой инвариант совместимости должен проверять интеграционный тест?

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

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

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

Проверка должна выполняться не только по валидности схемы, но и на связке «новый продюсер — старый потребитель». Иначе тест может подтвердить корректность структуры, но не выявить отказ потребителя при фактической обработке события.

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

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

Правила совместимости появились как способ снизить связанность между независимо поставляемыми компонентами. Основная исходная проблема — несовместимое изменение схемы, которое обнаруживается только после выката и приводит к отклонению сообщений, ошибкам обработки или потере бизнес-эффекта.

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

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

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

Ключевой риск определяется порядком развертывания. При стратегии «сначала продюсер» нужна обратная совместимость: старый потребитель должен понимать сообщения новой версии. При стратегии «сначала потребитель» дополнительно может потребоваться прямая совместимость: новый потребитель должен уметь читать старые сообщения.

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

Инвариант теста формулируется так: изменение схемы продюсера не должно делать ранее корректный потребитель неспособным принять и обработать событие. Для этого новая схема сравнивается с поддерживаемой предыдущей версией по правилам совместимости, а затем сообщение новой версии передается реальной или максимально близкой к реальной старой версии потребителя.

Обычно безопасным считается добавление необязательного поля при сохранении смысла, типа и формата существующих полей. Потребитель должен игнорировать неизвестные поля либо явно поддерживать их без нарушения обработки. Удаление поля, переименование, изменение типа, изменение единиц измерения или смена семантики существующего значения требуют отдельного плана совместимости.

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

Для независимого тестирования применяют версионирование схем, реестр схем с режимом совместимости, контрактные тесты продюсера и потребителя. Выбор инструмента вторичен: важнее явно зафиксировать направление совместимости, срок поддержки старых версий и реакцию на неизвестные поля.

У подхода есть ограничения. Нельзя автоматически объявлять любое добавление безопасным: если поле влияет на обязательное бизнес-решение, его отсутствие или значение по умолчанию может изменить результат. Кроме того, проверка схемы не гарантирует доставку, порядок, отсутствие дубликатов или успешное завершение побочных действий — это отдельные свойства интеграции.

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

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

Рассматривались три варианта. Первый — немедленно обновить всех потребителей; это просто концептуально, но нереалистично при независимом масштабировании и поэтапном развертывании. Второй — выпускать каждую модификацию под новым именем события; это изолирует изменения, но быстро увеличивает число обработчиков и усложняет миграцию.

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

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

  1. Достаточно ли проверить новую схему независимым валидатором?

Нет. Валидатор подтверждает соответствие сообщения заявленной схеме, но не показывает, способен ли старый потребитель его обработать. Нужна проверка совместимости между конкретной версией продюсера и каждой поддерживаемой версией потребителя либо формальная проверка правил эволюции схемы, дополненная поведенческим тестом.

  1. Почему удаление поля опасно, если потребитель не использует его в основном сценарии?

Потребитель может использовать поле не в основном пути, а в аудите, маршрутизации, дедупликации или диагностике. Кроме того, другая поддерживаемая версия потребителя может зависеть от него. Безопаснее сначала прекратить использование поля всеми потребителями, затем выдержать согласованный период совместимости и только после этого удалять его.

  1. Когда добавление необязательного поля всё равно ломает совместимость?

Оно ломает совместимость, если потребитель запрещает неизвестные поля, строго сравнивает весь объект, неверно обрабатывает значение по умолчанию или если новое поле меняет бизнес-смысл события. Поэтому контракт должен описывать не только обязательность и тип поля, но и правила неизвестных полей, допустимые значения, семантику отсутствия и порядок перехода между версиями.