개념
API 문서와 실제 동작이 다를 때
"API 문서에는 email 필드가 필수라고 되어 있는데, 실제로는 안
보내도 요청이 성공한다" — 이런 문서와 실제 동작의 불일치는
실무에서 흔하다. 이 API를 쓰는 다른 팀(프런트엔드, 다른
마이크로서비스)은 문서를 믿고 코드를 짜기 때문에, 이 불일치가
연쇄적인 결함으로 이어진다.
OpenAPI 스펙이란
OpenAPI(예전 이름 Swagger)는 API의 엔드포인트, 요청·응답 형식, 필수/선택 필드, 데이터 타입을 표준화된 형식(보통 YAML이나 JSON)으로 기술하는 명세다.
paths:
/orders:
post:
requestBody:
content:
application/json:
schema:
type: object
required: [productId, quantity]
properties:
productId:
type: string
quantity:
type: integer
minimum: 1
responses:
'201':
content:
application/json:
schema:
type: object
properties:
orderId:
type: string
totalPrice:
type: number이 명세는 "주문 생성 API는 productId와 quantity가 필수이고,
quantity는 1 이상이어야 하며, 성공 시 orderId와 totalPrice를
포함한 응답을 준다"는 **약속(Contract)**을 기계가 읽을 수 있는
형태로 적어둔 것이다.
계약 테스트(Contract Testing)란
이 명세(계약)와 실제 API 응답이 정확히 일치하는지 자동으로 검증하는 것이 계약 테스트다.
계약 테스트 = "명세에 적힌 대로 실제 API가 동작하는가?"를 자동 검증레슨 2의 어서션(totalPrice가 정확히 9000인지 확인)이 개별
값의 정확성을 확인한다면, 계약 테스트는 응답의 구조 자체가
명세와 일치하는지(필드가 다 있는가, 타입이 맞는가)를 확인한다는
점에서 다르다.
test("주문 생성 API 응답이 OpenAPI 스펙과 일치한다", async () => {
const response = await request(app).post("/orders").send(validOrder)
expect(response.status).toBe(201)
expect(response.body).toMatchSchema(orderResponseSchema) // 스펙 기반 스키마 검증
})계약 테스트가 잡아내는 결함
- 개발자가 API를 수정하면서 문서(스펙) 업데이트를 깜빡했다
- 필드 이름을 실수로 바꿨는데(
totalPrice→total_price) 아무도 눈치 못 챘다 - 필수였던 필드를 선택으로 바꿨는데, 이걸 쓰는 다른 팀에 미리 알리지 않았다
이런 결함은 모듈 6(레슨 1)의 결함 생명주기 관점에서 보면, API를 사용하는 쪽(프런트엔드, 다른 서비스)에서 늦게 발견될수록 더 큰 비용이 든다 — 계약 테스트는 이걸 API가 배포되는 시점에 즉시 잡아낸다.
스키마 검증과 값 검증은 함께 쓰인다
계약 테스트가 "구조가 맞는지"를 확인한다고 해서 레슨 2·3에서 배운 "값이 정확한지" 확인이 필요 없어지는 건 아니다. 두 검증은 서로 보완하는 관계다 — 구조가 맞아도 계산이 틀릴 수 있고, 계산이 맞아도 구조가 깨질 수 있다.
실무에서 왜 필요한가
여러 팀이 API를 공유하는 조직(마이크로서비스 환경)에서, "이 API를 쓰는 다른 팀에 미리 알리지 않고 응답 구조를 바꿔서 장애가 났다"는 사고는 매우 흔하다. 계약 테스트를 CI(모듈 14)에 포함시켜 두면, API 제공자가 계약을 어기는 변경을 하려는 순간 배포 전에 자동으로 걸러진다 — 이건 모듈 8(레슨 4)에서 배운 "테스트 완료 단계에서 배운 점을 조직 전략에 반영한다"는 원칙을, 아예 자동화된 안전장치로 만든 것이다.
실습 과제
과제 1 — 계약 위반 찾기 (10분)
이 레슨의 OpenAPI 스펙 예시를 기준으로, 다음 실제 응답이 계약을 위반하는 부분이 어디인지 찾는다.
{
"order_id": "ORD-123",
"totalPrice": "9000"
}과제 2 — 계약 테스트와 값 검증의 역할 나누기 (10분)
"주문 생성 API"를 테스트할 때, 계약 테스트로 확인할 항목과 개별 어서션(레슨 2·3)으로 확인할 항목을 각각 2가지씩 나눠 적는다.
자가 체크리스트
- OpenAPI 스펙이 무엇을 기술하는 문서인지 설명할 수 있다
- 계약 테스트가 값 검증과 어떻게 다른 것을 확인하는지 설명할 수 있다
- 계약 테스트가 왜 마이크로서비스 환경에서 특히 중요한지 설명할 수 있다
- 스키마 검증과 값 검증이 서로 보완적이라는 것을 설명할 수 있다
흔한 실수
- 계약 테스트만 있으면 값 검증은 필요 없다고 오해한다. 구조가 맞아도 계산 로직이 틀릴 수 있다 — 두 검증 모두 필요하다.
- API 문서(스펙)를 업데이트하지 않고 코드만 바꾼다. 계약 테스트가 실패로 잡아주긴 하지만,애초에 스펙과 구현을 함께 관리하는 습관이 먼저다.
- 필드 이름의 대소문자·표기법 차이(
totalPricevstotal_price)를 사소하다고 넘긴다. 이런 불일치가 실제로 연동 장애의 흔한 원인이다.
참고 자료
- OpenAPI Specification 공식 사이트 — OpenAPI 스펙 문법의 공식 레퍼런스
- ISTQB Glossary — Contract Testing — 계약 테스트의 공식 정의