Инженерная практика
Контрактное тестирование: построй гейт и переживи breaking-изменение
Читать про контрактное тестирование — не то же, что пережить момент, когда can-i-deploy краснеет в пятницу и говорит, что переименование, которое ты собирался выкатить, сломало бы prod. Подними настоящую пару потребитель/провайдер с брокером, докажи, что гейт работает, затем прогони через него breaking-переименование поля так, как сениор его реально выкатывает — без flag-day и без аварии.
Преврати ментальную модель юнита в рабочий пайплайн: consumer-driven pact, provider verification со state handler’ами, брокер, держащий матрицу верификации, гейт can-i-deploy, привязанный к git SHA и питаемый записями деплоев — затем прогони его, поймав breaking-изменение и безопасно выкатив его через expand-then-contract.
Подними небольшую систему из двух сервисов (потребитель и провайдер, напр. checkout-web, читающий цены из pricing API) с Pact-брокером, рабочим гейтом can-i-deploy и докажи end-to-end, что гейт блокирует breaking-изменение, а expand-then-contract выкатывает его безопасно — с доказательствами на каждом шаге.
- Зелёный прогон: pact потребителя опубликован, провайдер его верифицирует (включая хотя бы одно взаимодействие с provider state, засеянным обработчиком), и can-i-deploy выходит с 0 для совместимой пары.
- Красный прогон, захваченный как доказательство: переименование поля в одном PR валит provider verification и can-i-deploy выходит ненулевым, а матрица брокера показывает неверифицированную пару — доказывая, что гейт ловит поломку до деплоя.
- Последовательность expand-then-contract продемонстрирована end-to-end: провайдер с обоими полями едет (can-i-deploy зелёный), потребитель мигрирует независимо, старое поле удалено лишь после того, как матрица показала, что в prod его никто не читает — ни один шаг не требовал деплоить обе команды в lockstep.
- Абзац-объяснение, почему верификация проверяет минимальную ожидаемую форму, почему can-i-deploy задаёт другой вопрос, чем зелёная верификация, и почему record-deployment должен запускаться в конце rollout.
- Подключи webhook брокера (contract_requiring_verification_published), чтобы новый pact потребителя автоматически триггерил сборку верификации провайдера, и покажи, что два пайплайна никогда не вызывают друг друга напрямую.
- Добавь consumer-led изменение до того, как провайдер его реализует, и через pending- (или WIP-) pact'ы покажи, что основная сборка провайдера остаётся зелёной, всё ещё сообщая падающий результат обратно потребителю.
- Добавь намеренно неверное-но-хорошо-сформированное значение (напр. отрицательную цену) и покажи, что все контракты всё равно проходят — затем добавь тонкий e2e-smoke-тест, ловящий это, демонстрируя границу форма-не-семантика на практике.
- Подними bi-directional contract testing для одной пары (провайдер публикует OpenAPI-спеку, брокер сравнивает pact с ней) и сопоставь его покрытие и модель доверия с классическим путём provider-verification, который ты построил.
Это цикл, который ты будешь гонять на любой платформе независимо деплоящихся сервисов: потребитель записывает реальное использование по типу в pact, провайдер верифицирует, проигрывая против реального сервиса со state handler’ами, засевающими данные, брокер держит матрицу верификации, а can-i-deploy — привязанный к git SHA и питаемый честными записями деплоев — превращает эту матрицу в гейт деплоя. Как только ты почувствовал, как гейт ловит breaking-переименование, а затем выкатил то же переименование безопасно через expand-then-contract, production-версия перестаёт быть теорией: лови поломку до деплоя, эволюционируй без flag-day и держи тонкий e2e-smoke-слой ради семантики, которую контракты никогда не увидят.