소비자 주도 계약 테스트(Consumer-Driven Contract Testing)
1. 개요
가. 정의
서비스를 호출하는 측(소비자, Consumer) 이 자신이 실제로 보내고 기대하는 요청·응답의 형태를 계약(Contract) 으로 먼저 정의하고, 제공자(Provider) 가 그 계약을 만족하는지를 각자 독립적으로 검증함으로써, 두 서비스를 동시에 띄우지 않고도 인터페이스 호환성을 보장하는 테스트 기법.
소비자 주도 계약 테스트는 마이크로서비스처럼 독립 배포되는 서비스들이 서로 API로 통신하는 환경에서, "내 서비스는 멀쩡한데 상대 서비스가 응답 형식을 바꿔서 운영 중에 터졌다"는 고질적 문제를 구조적으로 막기 위한 접근이다. 핵심 발상은 계약의 주도권을 소비자에게 둔다는 점에 있다. 즉 제공자가 "나는 이런 API를 제공한다"고 일방적으로 선언하는 것이 아니라, 각 소비자가 "나는 네 API에서 이 필드만, 이런 형태로 쓴다"고 명시하고, 제공자는 자신을 쓰는 모든 소비자의 기대를 합집합으로 만족시키면 된다.
여기서 "소비자 주도"라는 수식어는 전통적 관점을 뒤집는다. 보통 인터페이스는 제공자가 설계해 내려주고 소비자가 거기에 맞추지만, 계약 테스트에서는 소비자의 실제 수요가 계약의 출발점이 된다. 제공자는 모든 가능한 사용법을 상상해 방어하는 대신, 지금 자신을 쓰는 소비자들의 구체적 기대만 만족시키면 된다.
이 방향 전환은 단순한 역할 바꾸기가 아니라 실질적으로 쓰이는 범위만 보증한다는 경제적 이점을 낳는다. 제공자가 응답에 10개 필드를 내려주더라도 어떤 소비자도 쓰지 않는 필드라면 자유롭게 바꿔도 아무도 깨지지 않으며, 반대로 단 하나의 소비자라도 쓰는 필드는 함부로 제거할 수 없다는 사실이 계약이라는 실행 가능한 명세로 고정된다. 계약은 사람이 읽는 문서가 아니라 기계가 검증하는 테스트이므로, 문서와 실제 코드가 따로 노는 전형적인 API 명세의 노후화 문제도 함께 해소된다.
나. 등장 배경 및 필요성
모놀리식 시대에는 모든 모듈이 한 프로세스 안에서 컴파일·배포되었기에, 인터페이스가 어긋나면 컴파일 단계나 통합 테스트에서 바로 드러났다. 그러나 수십 개 서비스가 각기 다른 팀·배포 주기·언어로 쪼개진 MSA에서는 이런 조기 피드백이 사라진다. 서비스 A의 응답 스키마 변경이 그 서비스를 쓰는 B·C·D에 어떤 영향을 주는지는 실제로 함께 실행해 보기 전까지 알 수 없고, 그 "실제"가 흔히 운영 환경이 되어 버린다.
전통적 대안인 종단 간(End-to-End) 통합 테스트는 이 문제를 정면으로 겨누지만 비용이 가혹하다. 연관된 모든 서비스와 데이터베이스·메시지 브로커를 한 환경에 띄워야 하므로 환경 구성이 무겁고 느리며, 한 서비스의 사소한 지연이나 테스트 데이터 오염만으로도 전체가 실패하는 깨지기 쉬움(flakiness) 에 시달린다. 수백 개 서비스 규모에서는 "전부를 한꺼번에 띄운다"는 전제 자체가 비현실적이다. 실제로 넷플릭스·스포티파이 같은 대규모 MSA 조직이 "통합 환경에서 전부를 검증한다"는 전략을 버리고 계약 테스트로 이동한 핵심 이유가 여기에 있다.
계약 테스트는 이 딜레마를, 각 쌍(소비자-제공자)의 상호작용만 떼어 내 독립적으로 검증함으로써 푼다. 소비자는 제공자를 흉내 낸 모의 서버(Mock) 를 상대로 테스트하되, 그 모의의 약속을 계약으로 산출하고, 제공자는 계약이 기술한 요청을 재생(replay) 받아 자신의 응답이 약속과 맞는지 검증한다. 두 검증은 각 팀의 CI에서 서로 다른 시점에 따로 돌지만, 계약이라는 공유 산출물을 매개로 "함께 띄우지 않고도 함께 검증한" 효과를 낸다.
이 접근이 비용 면에서 결정적으로 유리한 이유는 검증해야 할 조합의 수가 곱이 아니라 합으로 줄어들기 때문이다. 서비스가 N개이고 서로 M개의 연결을 맺을 때, 전체를 함께 검증하려면 환경 조합이 기하급수적으로 늘지만, 계약 테스트는 각 연결을 독립적으로 검증하므로 연결 수에 선형으로 비례하는 비용만 치른다. 이 확장성이야말로 수백 개 서비스 규모에서 계약 테스트가 사실상 유일한 현실적 선택지가 되는 근본 이유다.
2. 동작 원리와 전체 구조
계약 테스트의 전체 흐름은 "소비자가 계약을 생성 → 중앙 저장소(브로커)에 발행 → 제공자가 내려받아 검증"이라는 비동기 파이프라인으로 구성된다. 아래 그림은 소비자·제공자·브로커 사이의 산출물 흐름을 나타낸다.
flowchart LR
subgraph Consumer["소비자 팀 CI"]
CT["소비자 테스트(모의 서버 대상)"] --> PACT["계약 파일 생성(JSON)"]
end
PACT -->|publish| BROKER["계약 브로커(Pact Broker)"]
subgraph Provider["제공자 팀 CI"]
VER["계약 재생 및 실제 응답 검증"] --> RESULT["검증 결과 기록"]
end
BROKER -->|fetch| VER
RESULT -->|publish| BROKER
BROKER --> DEPLOY{"can-i-deploy 판정"}
동작의 핵심은 계약이 소비자 테스트의 부산물로 자동 생성된다는 점이다. 소비자는 제공자를 직접 호출하지 않고, 계약 테스트 프레임워크가 띄운 모의 서버를 상대로 평소처럼 단위 테스트를 작성한다. 이때 "GET /orders/123을 호출하면 id·status 필드를 가진 JSON이 온다고 가정한다"는 식의 기대(expectation) 를 선언하는데, 테스트가 통과하면 프레임워크가 그 상호작용을 계약 파일(interaction 목록) 로 직렬화한다. 즉 소비자는 계약을 따로 손으로 쓰지 않으며, 자신이 실제로 소비하는 패턴이 그대로 계약이 된다.
제공자 측 검증은 정반대 방향으로 흐른다. 제공자 CI는 브로커에서 자신을 대상으로 한 모든 계약을 가져와, 계약에 담긴 요청을 실제 제공자 애플리케이션에 그대로 재생하고 돌아온 실제 응답이 계약의 기대와 일치하는지 매처(matcher) 로 대조한다. 여기서 중요한 설계는 값의 완전 일치가 아니라 타입·구조 수준의 유연한 매칭을 쓴다는 점이다. 예컨대 id가 정확히 123인지가 아니라 "정수형인지", status가 "문자열이며 OPEN·CLOSED 중 하나인지"를 본다. 그래야 테스트 데이터의 구체 값에 종속되지 않고 인터페이스 계약만 안정적으로 검증할 수 있다.
이 비대칭 검증 구조—소비자는 생성하고 제공자는 재생한다—가 계약 테스트의 독창성이다. 두 팀은 서로의 코드나 배포 일정을 전혀 몰라도 되고, 오직 브로커에 쌓인 계약만 공유하면 된다. 덕분에 팀 간 느슨한 결합을 유지하면서도 인터페이스 호환성이라는 가장 깨지기 쉬운 지점만은 단단히 묶어 둘 수 있다. 이는 조직 구조가 아키텍처를 좌우한다는 콘웨이 법칙의 역이용—계약으로 팀 경계를 명시화해 오히려 독립성을 높이는—이라고 볼 수 있다.
마지막 단계인 배포 가능 판정(can-i-deploy) 은 계약 테스트를 실무에서 작동하게 만드는 핵심 장치다. 브로커는 어떤 소비자 버전과 어떤 제공자 버전 사이의 계약이 검증에 성공했는지를 버전 매트릭스로 축적하고 있으므로, 배포 직전에 "지금 운영에 떠 있는 상대 버전과 내 새 버전의 계약이 모두 초록불인가"를 질의해 안전할 때만 배포를 진행시킨다. 계약 검증이 통과했더라도 상대의 운영 버전과의 조합이 검증되지 않았다면 배포를 막는 것이다.
3. 유형·구성요소·절차
가. 접근 방식의 유형
계약 테스트는 누가 계약의 원천이 되느냐에 따라 나뉜다. 가장 널리 쓰이는 소비자 주도(Consumer-Driven) 방식은 앞서 설명한 대로 소비자의 실제 사용 패턴에서 계약이 흘러나오며, 미사용 필드에 대한 제공자의 자유도를 극대화한다는 장점이 있다. 반면 소비자가 많고 외부에 공개된 공용 API라면 모든 소비자의 계약을 모으기 어렵기 때문에, 제공자가 OpenAPI 명세를 원천으로 삼는 제공자 주도/스키마 기반 방식이 적합하다.
최근에는 두 방식의 장점을 결합한 양방향 계약 테스트(Bi-Directional Contract Testing) 가 부상했다. 이는 제공자가 발행한 OpenAPI 스펙과 소비자가 생성한 계약을 브로커가 정적으로 교차 비교하여, 제공자 애플리케이션을 실제로 재생·실행하지 않고도 호환성을 판정하는 방식이다. 제공자 검증 단계의 실행 비용을 크게 줄이는 대신, 스펙이 실제 구현을 정확히 반영한다는 전제에 의존한다는 한계가 있어 상황에 맞게 선택해야 한다.
조직 현실에서는 세 방식을 배타적으로 고르기보다 혼용하는 경우가 많다. 내부 팀 간 긴밀한 서비스는 소비자 주도로, 외부 파트너가 쓰는 공개 API는 양방향으로 운영하는 식이다. 선택의 기준은 "소비자 목록을 통제할 수 있는가"와 "제공자를 실제 실행해 검증할 여력이 있는가" 두 축으로 정리된다.
한편 계약 테스트를 스키마 레지스트리나 API 게이트웨이의 스키마 검증과 혼동하지 않는 것도 중요하다. 스키마 검증은 "메시지가 문법적으로 유효한가"만 보지만, 소비자 주도 계약은 "특정 소비자가 실제로 그 필드를 그렇게 쓴다"는 사용 맥락까지 담는다. 예컨대 OpenAPI 스펙상 선택(optional) 필드라도 어떤 소비자가 그것에 의존한다면, 그 소비자의 계약은 해당 필드를 사실상 필수로 못 박는다. 이처럼 계약은 명세보다 더 구체적이고 소비자 특화된 보증을 제공한다는 점에서 단순 스키마 검증의 상위 개념으로 볼 수 있다.
나. 핵심 구성요소
| 구성요소 | 역할 |
|---|---|
| 계약 파일(Pact/Contract) | 소비자가 기대하는 요청·응답을 기술한 JSON 산출물 |
| 모의 서버(Mock Provider) | 소비자 테스트가 상대하는 가짜 제공자 |
| 매처(Matcher) | 값이 아닌 타입·정규식·구조로 응답을 검증하는 규칙 |
| 계약 브로커(Broker) | 계약·검증결과·버전 매트릭스를 보관·공유하는 중앙 저장소 |
| 제공자 상태(Provider State) | "주문 123이 존재하는 상태" 같은 재생 전 사전조건 |
| can-i-deploy | 배포 안전성을 버전 매트릭스로 판정하는 도구 |
이 구성요소들 가운데 실무에서 가장 자주 오해되는 것이 제공자 상태(Provider State) 다. 계약에 "GET /orders/123이 200을 반환한다"가 담겨 있어도, 제공자 CI에서 그 주문이 DB에 없으면 404가 나 검증이 실패한다. 그래서 각 상호작용에는 "given: 주문 123이 존재함" 같은 사전조건이 붙고, 제공자는 재생 직전에 그 상태를 셋업하는 훅을 구현해 데이터를 준비한다. 이 장치 덕분에 계약 검증이 특정 운영 데이터에 종속되지 않고 재현 가능해진다.
다. 적용 절차
실무 절차는 소비자·제공자 두 파이프라인이 브로커를 매개로 느슨하게 동기화되는 형태로 돌아간다. 아래 다이어그램은 코드 변경에서 배포 판정까지의 순서를 나타낸다.
sequenceDiagram
participant C as "소비자 CI"
participant B as "계약 브로커"
participant P as "제공자 CI"
C->>C: "모의 서버 대상 소비자 테스트 실행"
C->>B: "계약 발행(버전·브랜치 태그)"
B->>P: "webhook: 신규 계약 알림"
P->>B: "대상 계약 조회"
P->>P: "제공자 상태 셋업 후 계약 재생·검증"
P->>B: "검증 결과 발행"
C->>B: "배포 전 can-i-deploy 질의"
B-->>C: "매트릭스 기반 배포 가부 응답"
절차에서 놓치기 쉬운 지점은 계약 변경이 제공자 검증을 자동으로 촉발해야 한다는 것이다. 소비자가 새 필드를 요구하는 계약을 발행하면 브로커가 웹훅으로 제공자 CI를 깨워 즉시 검증하게 하고, 그 결과가 다시 매트릭스에 쌓인다. 이렇게 "발행-검증-판정"이 자동 연쇄를 이루어야 계약 테스트가 사람의 수작업 조율 없이 배포 게이트로 기능한다.
버전 식별 전략도 절차의 숨은 핵심이다. 계약과 검증 결과는 반드시 커밋 해시 같은 불변 식별자와 main·feature/* 같은 브랜치 태그로 함께 기록되어야, can-i-deploy가 "운영에 떠 있는 바로 그 버전"과의 호환성을 정확히 질의할 수 있다. 버전을 느슨하게 관리하면 매트릭스가 어긋나 "검증은 통과했는데 실제로는 깨지는" 최악의 상황이 발생한다.
라. 흔한 안티패턴과 모범사례
계약 테스트는 올바로 쓰지 않으면 오히려 거짓 안정감과 유지보수 부담만 키운다. 가장 흔한 실패는 매처를 쓰지 않고 응답의 구체 값을 그대로 계약에 박아 넣는 것이다. 이렇게 하면 제공자가 테스트 데이터를 조금만 바꿔도 계약이 깨져, 인터페이스는 멀쩡한데도 검증이 실패하는 취약한(brittle) 계약이 된다. 계약은 값이 아니라 타입·구조·제약을 기술해야 한다는 원칙이 여기서 나온다.
또 다른 안티패턴은 소비자가 실제로 쓰지 않는 필드까지 계약에 포함시키는 과잉 명세다. 이는 소비자 주도 방식의 핵심 이점—제공자의 변경 자유도—을 스스로 깎아먹는다. 소비자는 자신이 정말 읽는 필드만 최소한으로 선언해야 하며, 그래야 제공자가 나머지를 자유롭게 진화시킬 수 있다. 반대로 제공자가 can-i-deploy를 배포 게이트로 강제하지 않고 참고용으로만 두는 것도 흔한 실패인데, 이 경우 계약은 깨져도 배포를 막지 못해 사실상 장식으로 전락한다.
| 안티패턴 | 모범사례 |
|---|---|
| 구체 값을 계약에 하드코딩 | 매처(타입·정규식·구조)로 유연하게 기술 |
| 미사용 필드까지 과잉 명세 | 실제 소비 필드만 최소 선언 |
| can-i-deploy를 참고용으로만 사용 | CI/CD 배포 게이트로 강제 통합 |
| 제공자 상태 셋업 누락 | given 사전조건 훅으로 재현성 확보 |
4. 통합 테스트와의 비교 및 적용 사례
계약 테스트와 통합 테스트는 대체재가 아니라 서로 다른 실패를 잡는 보완재다. 계약 테스트는 "인터페이스 모양이 맞는가(syntactic/structural)"를 싸고 빠르게 검증하는 데 강하지만, 여러 서비스가 엮인 비즈니스 흐름 전체가 의도대로 동작하는가는 보지 못한다. 반대로 통합 테스트는 그 전체 흐름을 보지만 비싸고 불안정하다. 그래서 테스트 피라미드 관점에서는 다수의 계약 테스트 + 소수의 핵심 시나리오 E2E로 구성하는 것이 비용 대비 효과가 가장 좋다.
| 구분 | 계약 테스트 | E2E 통합 테스트 |
|---|---|---|
| 검증 대상 | 두 서비스 간 인터페이스 호환성 | 다수 서비스의 end-to-end 흐름 |
| 실행 방식 | 각 서비스 독립 실행(함께 안 띄움) | 전체 환경 동시 기동 |
| 속도·안정성 | 빠르고 안정적 | 느리고 flaky |
| 피드백 시점 | 각 팀 CI(배포 전) | 통합 환경(후반) |
| 못 잡는 것 | 복합 비즈니스 로직·성능 | 빠른 조기 피드백·비용 효율 |
차이가 생기는 근본 이유는 격리의 단위에 있다. 계약 테스트는 상호작용을 쌍 단위로 쪼개 격리하기 때문에 조합 폭발을 피하지만, 바로 그 격리 때문에 "A→B→C가 연쇄될 때만 드러나는 오류"는 구조적으로 볼 수 없다. 이 트레이드오프를 이해해야 "계약 테스트를 도입했으니 통합 테스트를 없애도 된다"는 흔한 오판을 피할 수 있다.
피드백 시점의 차이도 실무적으로 중요하다. 계약 테스트는 각 팀의 CI에서 배포 전에 호환성 깨짐을 알려 주므로, 문제를 만든 개발자가 맥락을 생생히 기억하는 순간에 즉시 수정할 수 있다. 반면 통합 환경 E2E는 여러 서비스가 모인 후반 단계에서 실패하므로, 원인 서비스를 역추적하는 데만 상당한 시간이 들고 책임 소재도 흐려진다. "결함을 일찍 발견할수록 수정 비용이 기하급수적으로 싸진다"는 소프트웨어 공학의 오랜 원칙이 계약 테스트의 가치를 뒷받침하는 셈이다.
또한 "계약을 도입했으니 통합 테스트를 없애도 된다"는 오판만큼 흔한 것이 그 반대, 즉 계약 테스트를 E2E의 축소판으로 오해하는 것이다. 계약 테스트에 복잡한 비즈니스 분기나 다단계 워크플로를 욱여넣으면 계약이 비대해지고 깨지기 쉬워져, 결국 느린 통합 테스트의 단점만 물려받게 된다. 계약은 어디까지나 인터페이스의 모양에 집중하고, 흐름의 정합성은 소수의 E2E로 넘기는 역할 분담이 지켜져야 두 기법이 각자의 강점을 발휘한다.
구체적 적용 사례로, 글로벌 결제 플랫폼이 수백 개 내부 서비스 간 통신에 Pact 기반 계약 테스트를 도입해 배포 전 호환성 검증을 자동화한 사례가 널리 인용된다. 한 소비자 결제 서비스가 응답에서 currency 필드를 필수로 기대하도록 계약을 발행하면, 정산 제공자 서비스가 그 필드를 제거하는 변경을 배포하려는 순간 can-i-deploy가 빨간불을 띄워 운영 장애를 사전 차단한다. 국내에서도 다수의 서비스를 독립 배포하는 커머스·금융 플랫폼들이 통합 환경 E2E의 유지 비용과 flaky 실패에 지쳐 계약 테스트로 이동하는 흐름이 뚜렷하다. 수치로 보면, E2E 스위트 한 번에 수십 분이 걸리던 호환성 검증이 계약 테스트에서는 서비스별 수초~수십초 단위로 떨어지는 효과가 보고된다.
5. 심화: 최신 동향과 생태계
계약 테스트가 하나의 품질 공학 기법으로 자리 잡기까지는 마틴 파울러 등이 정리한 소비자 주도 계약(Consumer-Driven Contracts) 개념과, 이를 다국어·브로커 중심 워크플로로 구현한 오픈소스 도구의 등장이 결정적이었다. 초기에는 "모의 서버를 쓰면 실제와 달라 믿을 수 없다"는 회의가 있었으나, 모의의 약속을 계약으로 산출해 제공자가 그 약속을 실제로 지키는지 되검증하는 구조가 이 간극을 메우면서 신뢰를 얻었다.
계약 테스트 생태계는 특정 도구를 중심으로 빠르게 성숙하고 있다. 사실상 표준으로 자리 잡은 Pact는 다국어(Java·JS·.NET·Go·Python 등) 라이브러리와 Pact Specification을 제공하며, 상용 관리형 브로커인 PactFlow는 양방향 계약 테스트와 can-i-deploy·배포 기록을 통합 제공한다. JVM 진영에서는 Spring Cloud Contract가 제공자 주도 방식으로 계약을 두고 소비자용 스텁을 생성하는 상호 보완적 접근을 제공하며, 비동기 메시지(Kafka·RabbitMQ) 계약 검증도 지원 범위에 들어와 있다.
최근 가장 주목할 변화는 계약 테스트가 동기 REST를 넘어 이벤트 기반(비동기) 통신으로 확장되고 있다는 점이다. 메시지 발행자(제공자)와 구독자(소비자) 사이에서도 "이 토픽의 메시지는 이런 스키마를 가진다"는 계약을 교환함으로써, 스키마 레지스트리(Confluent Schema Registry 등)의 호환성 모드와 결합해 이벤트 스키마 진화를 안전하게 관리하는 방향으로 발전하고 있다. 동기 호출과 달리 비동기에서는 소비자가 언제 메시지를 처리할지 제어할 수 없으므로, "발행 시점의 스키마"와 "소비 시점의 스키마"가 어긋나는 시간차 호환성 문제가 더 중요해지는데, 계약 테스트가 이 간극을 배포 전에 드러내는 역할을 맡는다.
또한 OpenAPI·AsyncAPI 같은 API 명세 표준과의 통합이 강화되면서, 명세를 원천으로 한 양방향 검증이 대규모·공개 API 환경에서 현실적 대안으로 부상했다. 명세가 단일 진실원천(SSOT)으로 자리 잡으면 문서·모의 서버·계약 검증이 모두 한 소스에서 파생되므로 불일치 위험이 줄어든다. 다만 이런 자동화는 생성형 AI가 작성한 계약·스텁의 품질 검증, 조직 전반의 계약 거버넌스, 수백 개 계약의 버전 매트릭스 폭발을 어떻게 관리할 것인가 같은 새로운 운영 과제를 동반한다. 결국 도구의 성숙도만큼이나 계약을 1급 산출물로 다루는 조직 문화가 성패를 가른다.
6. 고려사항 및 시사점
- 적용 전략(선별적 도입): 모든 서비스 쌍에 계약 테스트를 강제하면 계약 관리 부담이 급증한다. 변경이 잦고 장애 파급이 큰 핵심 내부 서비스 간 통신에 우선 적용하고, 안정적이거나 외부 공개 API는 양방향·스키마 기반으로 차등 운영하는 선별 전략이 바람직하다.
- 트레이드오프(격리 vs 완전성): 계약 테스트는 속도·안정성을 얻는 대신 종단 비즈니스 흐름의 정합성은 포기한다. 따라서 계약 테스트로 통합 테스트를 전부 대체하려는 시도는 위험하며, 소수의 핵심 시나리오 E2E와 병행해 피라미드를 설계해야 한다. 또한 양방향 방식은 비용을 줄이는 대신 "스펙=구현" 가정에 의존하는 위험을 안는다.
- 조직·거버넌스 과제: 계약 테스트의 성패는 기술보다 팀 간 협업 규약에 달려 있다. 브로커·버전 태깅·can-i-deploy를 배포 게이트로 CI/CD에 강제 통합하고, 계약 변경 시 영향받는 소비자 팀과의 커뮤니케이션 절차를 명문화해야 한다. 계약을 깨는 변경에 대한 책임·승인 주체가 불명확하면 계약은 금세 형해화된다.
- 연계 기술 및 전망: 계약 테스트는 MSA·API 게이트웨이·스키마 레지스트리·CI/CD·GitOps와 긴밀히 맞물린다. 배포 파이프라인의 품질 게이트(can-i-deploy)로 작동할 때 가치가 극대화되며, 향후에는 이벤트 기반 아키텍처와 AI 보조 계약 생성이 결합되면서 분산 시스템의 "배포 안전망" 표준으로 자리 잡을 전망이다. 기술사 관점에서는 테스트 전략을 비용·위험 기반으로 포트폴리오화하는 품질 거버넌스 설계 역량으로 이 주제를 다루어야 한다.
참고자료
- Pact Documentation, https://docs.pact.io/
- PactFlow, "Bi-Directional Contract Testing", https://pactflow.io/bi-directional-contract-testing/
- martinfowler.com, "Contract Test", https://martinfowler.com/bliki/ContractTest.html
- Spring Cloud Contract Reference, https://docs.spring.io/spring-cloud-contract/reference/
한 줄 요약: 소비자 주도 계약 테스트는 소비자가 실제 사용 패턴을 계약으로 만들고 제공자가 이를 독립 검증하여, 서비스를 함께 띄우지 않고도 인터페이스 호환성을 배포 전에 보장하는 MSA 테스트 전략으로, E2E 통합 테스트의 비용·불안정성을 보완하되 종단 비즈니스 흐름 검증과는 병행해야 한다.