"완성된" MERN 스택 Zerodha 클론에 Specmatic의 계약 테스트를 실행하자마자, 수동 점검으로는 절대 잡아낼 수 없었던 5가지 실제 결함이 발견되었습니다. 생성된 178개의 테스트 케이스 중, 이 테스트 스위트는 실제 사용자에게 영향을 미쳤을 법한 방식으로 API를 망가뜨렸습니다. 잘못된 데이터 타입, 잘못된 형식의 인증 정보로 인한 충돌, 조용한 데이터 손상, 비멱등성(non-idempotent) 회원가입, 그리고 CI 게이트를 즉시 중단시킨 계약 위반 변경 사항 등이 그것입니다.

수동 테스트에서 버그가 누락된 이유

이 프로젝트는 Node.js 백엔드, React 프론트엔드, MongoDB 저장소, 그리고 결제를 위한 Razorpay를 결합했습니다. 회원가입과 결제 흐름을 수동으로 진행했을 때는 모든 것이 정상적으로 작동하는 것처럼 보였습니다. 하지만 수동 테스트는 '해피 패스(happy path)'만을 실행합니다. 즉, 사용자가 의도된 단계를 따를 때 코드가 제대로 작동하는지만 확인합니다. 서비스가 잘못된 형식의 요청이나 예상치 못한 클라이언트 동작에서도 견딜 수 있는지는 증명하지 못합니다.

Specmatic을 기존 코드에 적용했을 때, 각 엔드포인트의 요청 및 응답 형태를 명시적으로 설명하는 '계약(contract)'이 신뢰할 수 있는 기준(source of truth) 역할을 했습니다. 그런 다음 도구는 사람이 작성하기 어려운 수많은 긍정적 및 부정적 시나리오를 포함한 방대한 매트릭스를 자동으로 생성했습니다.

발견된 5가지 결함

  • 입력 유효성 검사 공백/newOrder 엔드포인트는 계약상 정수(integer)를 요구함에도 불구하고 quantity 필드에 소수점 숫자와 문자열을 허용했습니다. 잘못된 타입을 전송하는 생성된 테스트로 인해 API가 오작동했습니다.
  • 처리되지 않은 로그인 오류 – 인증 경로에 잘못된 형식의 인증 정보를 제공했을 때, 코드에 타입 체크가 누락되어 런타임 예외(runtime exception)가 발생했습니다.
  • 조용한 결제 데이터 손상/verify-payment 엔드포인트는 amount 필드에 불리언(boolean) 값을 허용했습니다. true 값이 전달되었을 때, 데이터베이스는 결제 금액을 0으로 기록하여 성공적인 결제로 처리했고, 이는 매출 수치를 조용히 부풀리는 결과를 초래했습니다.
  • 멱등성(Idempotency) 누락 – 테스트 스위트에서 회원가입 흐름을 두 번째로 실행했을 때 실패했습니다. 엔드포인트가 중복된 사용자를 우아하게 처리하는 대신 기존 사용자를 다시 생성하려고 시도했기 때문입니다.
  • 계약 위반 변경 사항 포착 – 의도적으로 계약의 데이터 타입을 변경했습니다. CI 파이프라인이 즉시 이 변경 사항을 거부하여, 서비스 중단을 초래할 수 있는 릴리스를 방지했습니다.

CI 파이프라인에서 계약 테스트가 중요한 이유

  • 대규모 네거티브 테스트 – 178개 케이스의 대부분은 엣지 케이스(edge-case) 입력이었습니다. 이를 수동으로 작성하는 것은 엄청난 시간이 소요됩니다.
  • 서드파티 클라이언트를 위한 안전성 – 계약은 서비스가 외부 소비자에게 약속하는 내용을 정의합니다. 구현 내용이 계약에서 벗어나면 계약 테스트가 실패하여 다운스트림 앱을 보호합니다.
  • 빠른 피드백 루프 – CI 게이트가 병합 전 결함이 있는 변경 사항을 차단하여, 팀이 비용이 많이 드는 롤백을 수행하는 상황을 방지했습니다.
  • 코드 품질 향상 – 계약 테스트가 가능하도록 액추에이터(actuator) 엔드포인트를 추가하고 회원가입 흐름을 멱등하게 만든 과정은 결과적으로 서비스를 더욱 견고하게 만들었습니다.

개발자가 고려해야 할 트레이드오프(Trade-off)

계약 테스트는 유지보수 오버헤드를 발생시킵니다. 명세(specification)는 코드와 동기화되어야 하며, 테스트 생성 프로세스로 인해 빌드 시간이 길어질 수 있습니다. 팀은 특히 수동 테스트로 충분하다고 느껴지는 소규모 프로젝트의 경우, 추가된 안전성이 추가적인 노력을 정당화할 수 있는지 결정해야 합니다.

향후 주목할 점

  • CI 도입 확대 – 더 많은 팀이 계약 테스트 스위트를 파이프라인에 통합함에 따라, 도구는 더 빨라지고 설정 가능성도 높아질 것입니다.
  • 표준화된 계약 형식 – 새롭게 등장하는 명세들은 서비스와 팀 간에 계약을 더 쉽게 공유할 수 있게 해줄 것입니다.
  • 명세 업데이트 자동화 – 코드 변경 사항으로부터 계약을 추론하는 도구들이 수동 유지보수 부담을 줄여줄 수 있습니다.

UI가 매끄럽게 작동한다고 해서 API가 견고할 것이라고 가정한다면, 계약 테스트를 통해 수동 점검으로는 놓칠 수 있는 숨겨진 결함을 찾아낼 수 있습니다. CI 파이프라인에 실행 가능한 계약을 추가하면 "괜찮아 보이네"를 "안전함이 증명됨"으로 바꿀 수 있습니다.

Repository: https://github.com/priya3054/zerodha-specmatic