Контрактные тесты: Pact, проверка proto и GraphQL-схем
↑ 5.7 Тестирование интеграций · ← Предыдущая · → Следующая
Зачем это на собесе
Как командам микросервисов не ломать друг друга при изменениях API.
Объяснение
Контрактный тест проверяет, что обе стороны интеграции согласны с форматом сообщений, не поднимая всю систему.
Consumer-driven contracts (Pact):
- Потребитель описывает ожидаемые запросы и ответы, тест на моке провайдера формирует файл-контракт (pact).
- Контракт публикуется в Pact Broker.
- Поставщик в CI проигрывает контракты против реальной реализации.
can-i-deployблокирует релиз, ломающий контракт потребителей.
var pact = Pact.V4("orders-ui", "orders-api", new PactConfig());
var http = pact.WithHttpInteractions();
http.UponReceiving("get order").Given("order 42 exists")
.WithRequest(HttpMethod.Get, "/orders/42")
.WillRespond().WithStatus(200).WithJsonBody(new { id = 42, status = Match.Type("paid") });
await http.VerifyAsync(async ctx => { var o = await new OrdersClient(ctx.MockServerUri).GetAsync(42); Assert.Equal("paid", o.Status); });Для схем без Pact:
| Технология | Проверка |
|---|---|
| OpenAPI | линтер (Spectral), сравнение схем (oasdiff breaking) |
| gRPC/proto | buf breaking против основной ветки |
| GraphQL | graphql-inspector diff, проверка на реальных запросах клиентов |
| События (Kafka) | Schema Registry с режимом совместимости |
Нюансы и подводные камни
- Контракт описывает то, что реально использует потребитель, а не всю схему.
- Состояния провайдера («order 42 exists») нужно уметь подготавливать в тесте провайдера.
- Проверка схем ловит структурные поломки, но не смысловые (изменение семантики поля).
- Без culture «сначала контракт» тесты становятся формальностью: включайте проверки в CI как блокирующие.
Практика
- Настройте Pact между фронтендом и API (или двумя сервисами) с Pact Broker.
- Добавьте
buf breakingиoasdiffв CI. - Смоделируйте ломающее изменение и убедитесь, что CI его блокирует.
Вопросы с ответами
Что такое consumer-driven contract?
Контракт формируется по ожиданиям потребителя; поставщик обязан их выполнять, иначе релиз блокируется.
Чем контрактные тесты лучше e2e для проверки интеграции?
Быстрые, изолированные, не требуют поднимать все сервисы, локализуют поломку.