본문으로 건너뛰기
중급약 40분

ATDD·예제 기반 명세(Specification by Example) 실습

ATDD 는 대화에서 예제를 뽑고 그 예제를 자동화해 살아 있는 문서로 만드는 흐름이다. 발견·정제·자동화 3단계 워크숍 진행법, 좋은 Given-When-Then 과 나쁜 Given-When-Then, 예제 표로 규칙을 압축하는 법, 그리고 Gherkin 문법을 쓴다고 ATDD 가 되는 것이 아닌 이유를 실제 예제로 다룬다.

  • #ATDD
  • #예제기반명세
  • #BDD
  • #Gherkin
  • #살아있는문서

개념

ATDD 는 테스트 기법이 아니라 대화 방식이다

ATDD(Acceptance Test Driven Development)를 "인수 테스트를 먼저 쓰는 것"이라고 요약하면 절반만 맞다. 핵심은 무엇을 만들지 합의하는 방법 이고, 그 합의를 예제 형태로 굳힌 결과물이 자동화된 인수 테스트로 남는 것이다.

   대화(Discuss)          예제(Illustrate)         자동화(Automate)
  ────────────────  →  ────────────────────  →  ──────────────────
  요구를 놓고 질문     합의를 구체적 예로      예제를 실행 가능한
  하고 모호함을 드러냄   바꿔 적는다             테스트로 만든다
        ↑                                              │
        └──────────  예제가 안 맞으면 다시 대화로  ─────┘

순서가 중요하다. 대화 없이 예제부터 쓰면 그것은 ATDD 가 아니라 그냥 테스트 케이스 고, 예제 없이 자동화부터 하면 자동화가 요구사항과 따로 논다.

ATDD·BDD(Behaviour Driven Development)·예제 기반 명세(Specification by Example)는 강조점이 다르지만 실무에서 겹친다.

용어강조점주로 나오는 맥락
ATDD인수 기준을 먼저 합의하고 그것으로 개발을 이끈다팀 프로세스
BDD시스템의 "행위"를 공통 언어로 기술한다도구·문법(Gherkin)
Specification by Example명세를 추상적 문장 대신 구체적 예제로 쓴다요구사항 기법

이 레슨은 세 용어의 차이를 외우는 데 쓰지 않는다. 셋이 공유하는 실행 가능한 절차 를 익히는 것이 목적이다.

왜 "예제"인가 — 추상 문장은 두 사람에게 다르게 읽힌다

요구사항 문장 하나를 보자.

장바구니 금액이 일정 기준 이상이면 배송비가 무료가 된다.

개발자 A는 "상품 금액 합계"로 읽고, 기획자 B는 "쿠폰 적용 후 결제 금액"으로 읽는다. 둘 다 이 문장을 읽고 고개를 끄덕였지만 다른 시스템을 상상하고 있다. 이 불일치는 코드가 나온 뒤에 발견된다.

예제는 이 불일치를 대화 중에 드러낸다.

상품 합계쿠폰 할인결제 금액배송비왜
49,000049,0003,000기준 미달
50,000050,0000기준 충족
55,00010,00045,000?여기서 대화가 멈춘다

세 번째 행에서 A와 B의 답이 갈린다. 그 순간이 ATDD 가 값을 만드는 지점이다. 표를 채우다 말고 "이건 어떻게 되나요"를 묻는 일 — 그게 전부다. 답이 정해지면 그 행이 그대로 인수 기준이 된다.

예제 기반 명세 워크숍 — 3단계

실제 진행은 발견 → 정제 → 자동화 로 나눈다. 세 단계를 한 회의에서 다 하려 하면 셋 다 어설프게 끝난다.

[1단계 발견 Discovery]   25~30분, 스토리 1~2개
  참석: PO/BA + 개발 + 테스터  (세 역할이 반드시 함께 — "three amigos")
  산출: 규칙 목록, 예제 초안, 질문 목록
  방법: 예제 매핑(Example Mapping) — 4색 카드
        노랑: 스토리          파랑: 규칙(Rule)
        초록: 예제(Example)    빨강: 질문(Question)
 
  진행:
    1) 노랑 카드에 스토리를 붙인다
    2) 알고 있는 규칙을 파랑 카드로 뽑는다
    3) 각 규칙 아래 구체적 예제를 초록 카드로 붙인다
    4) 답이 없는 것은 빨강 카드로 남기고 넘어간다 (그 자리에서 토론하지 않는다)
 
  종료 판정:
    - 빨강이 많다  → 이 스토리는 아직 개발 착수 준비가 안 됐다
    - 파랑이 많다  → 스토리가 너무 크다. 쪼갠다
    - 초록만 잔뜩  → 규칙을 못 뽑고 케이스만 나열한 것. 다시 본다
 
[2단계 정제 Formulation]   20~30분, 보통 2명이면 충분
  산출: 공통 언어로 쓴 시나리오 (Gherkin 이든 표든)
  포인트: 여기서 "우리 도메인 용어"를 고정한다
          "고객/회원/사용자"가 섞여 있으면 지금 하나로 정한다
 
[3단계 자동화 Automation]   개발과 함께
  산출: 실행되는 인수 테스트
  포인트: 시나리오는 그대로 두고 단계 정의(step definition)만 바꿔 붙인다
          UI 를 거치지 않고 서비스 계층에 붙일 수 있으면 그쪽을 먼저 본다

1단계에서 빨강 카드를 그 자리에서 해결하려 하지 않는 것 이 운영의 핵심이다. 답을 아는 사람이 그 방에 없는 경우가 대부분이고, 토론을 시작하면 25분 워크숍이 두 시간이 된다. 빨강 카드는 담당자와 기한을 붙여 밖으로 내보낸다.

Given-When-Then — 좋은 예와 나쁜 예

Gherkin 의 세 키워드는 각각 역할이 정해져 있다. Given 은 맥락, When 은 하나의 행위, Then 은 관찰 가능한 결과 다. 이 역할이 섞이면 시나리오가 망가진다.

나쁜 예 1 — UI 조작 절차를 그대로 옮겼다.

Scenario: 배송비 무료
  Given 브라우저를 연다
  And 로그인 페이지로 이동한다
  And 아이디 입력란에 "test01" 을 입력한다
  And 비밀번호 입력란에 "pw1234" 를 입력한다
  And 로그인 버튼을 클릭한다
  When 상품 목록에서 첫 번째 상품을 클릭한다
  And 장바구니 담기를 클릭한다
  And 장바구니로 이동한다
  Then 배송비가 0원이다

문제는 셋이다. (1) 무엇을 검증하는지 읽어도 모른다. (2) 버튼 이름이 바뀌면 시나리오가 깨진다 — 규칙은 그대로인데. (3) 현업이 이 문서를 읽지 않는다. Gherkin 은 조작 스크립트가 아니라 규칙의 서술이어야 한다.

나쁜 예 2 — When 이 여러 개고 Then 에 검증이 뭉쳐 있다.

Scenario: 주문 처리
  Given 회원이 로그인해 있다
  When 주문을 생성하고 결제를 완료하고 배송지를 변경한다
  Then 주문이 생성되고 결제가 승인되고 배송지가 바뀌고 메일이 발송된다

실패하면 무엇이 깨졌는지 알 수 없다. 한 시나리오 = 한 행위 = 한 규칙 으로 자른다.

나쁜 예 3 — 결과가 관찰 불가능하다.

  Then 시스템이 정상적으로 동작한다
  Then 데이터가 올바르게 처리된다

"정상"과 "올바르게"는 판정 불가다. 이 문장은 레슨 4에서 다룰 RFP 의 모호한 표현과 같은 병이다.

좋은 예 — 규칙 하나를 도메인 언어로 서술한다.

Scenario: 쿠폰 적용 후 결제 금액이 기준 미만이면 배송비가 부과된다
  Given 장바구니에 상품 합계 55,000원이 담겨 있다
  And 10,000원 할인 쿠폰이 적용되어 있다
  When 결제 금액을 계산한다
  Then 결제 금액은 45,000원이다
  And 배송비 3,000원이 부과된다

읽으면 규칙이 보이고, 버튼 이름이 바뀌어도 이 문서는 유효하다.

예제 표로 규칙을 압축한다

같은 규칙의 경계값을 시나리오 5개로 늘어놓으면 문서가 길어지고 읽히지 않는다. 표로 묶는다.

Scenario Outline: 결제 금액 기준 배송비 산정
  Given 장바구니 상품 합계가 <상품합계>원이다
  And 쿠폰 할인이 <쿠폰할인>원이다
  When 결제 금액을 계산한다
  Then 결제 금액은 <결제금액>원이다
  And 배송비는 <배송비>원이다
 
  Examples: 무료배송 기준 50,000원 (결제 금액 기준)
    | 상품합계 | 쿠폰할인 | 결제금액 | 배송비 |
    | 49,999  | 0       | 49,999  | 3,000 |
    | 50,000  | 0       | 50,000  | 0     |
    | 55,000  | 10,000  | 45,000  | 3,000 |
    | 60,000  | 10,000  | 50,000  | 0     |
    | 0       | 0       | 0       | 0     |

마지막 행이 중요하다. 빈 장바구니에서는 배송비 계산 자체가 일어나지 않는다 는 규칙이 표를 채우는 과정에서 드러났다. 표는 경계값 분석(모듈 3)을 요구사항 대화에 끌어오는 장치이기도 하다.

표를 쓸 때 지킬 것이 하나 있다. 입력 조합을 기계적으로 곱하지 않는다. 5개 컬럼에 값 3개씩이면 243행이 되는데, 그건 명세가 아니라 데이터 덤프다. 예제는 규칙을 설명하는 최소 집합이어야 하고, 조합 폭발은 자동화 계층의 데이터 주도 테스트로 내려보낸다.

살아 있는 문서(living documentation)

예제가 자동으로 실행되면, 그 문서는 거짓말을 할 수 없는 문서 가 된다. 시스템이 바뀌었는데 문서가 안 바뀌면 빌드가 빨개지기 때문이다.

성립 조건이 있다.

조건안 지키면
CI 에서 매번 실행된다오래된 시나리오가 통과 상태로 굳는다
실패를 방치하지 않는다빨간 상태가 일상이 되고 문서 신뢰가 사라진다
결과가 사람이 읽는 형태로 발행된다개발자만 보는 로그로 남는다
도메인 언어로 쓰였다현업이 안 읽고, 안 읽는 문서는 안 고쳐진다
규칙 단위로 정리돼 있다검색이 안 되고 중복이 쌓인다

세 번째 조건 때문에 Cucumber·SpecFlow·Behave 계열은 HTML 리포트 발행 기능을 갖고 있다. 실무에서는 그 리포트를 사내 위키나 문서 사이트에 붙여 두고, 요구사항 문의가 오면 그 링크로 답하는 것 을 규칙으로 만든다. 그렇게 해야 문서가 실제로 문서 역할을 한다.

Gherkin 을 쓴다고 ATDD 가 되는 게 아니다

이 레슨에서 가장 오래 기억해야 할 문장이다. 현장에서 반복되는 실패 패턴은 이렇다.

1. 팀이 Cucumber 를 도입한다
2. 개발자가 기존 테스트 코드를 Gherkin 으로 감싼다
3. feature 파일이 300개가 된다
4. 현업은 한 번도 읽지 않는다
5. step definition 이 중복되고 유지보수가 무거워진다
6. "Cucumber 가 느려서" 걷어낸다
7. 결론: "BDD 는 우리 팀에 안 맞는다"

무엇이 빠졌는지는 분명하다. 1단계 대화가 없었다. 대화가 없으면 Gherkin 은 테스트 코드 위에 씌운 장식 레이어일 뿐이고, 그 레이어는 비용만 발생시킨다.

판정 기준을 하나 제시한다.

feature 파일을 개발자가 아닌 사람이 마지막으로 읽거나 고친 것이 언제인가?

기억나지 않으면, 그 팀은 ATDD 를 하고 있지 않다. Gherkin 을 걷어내고 평범한 테스트 코드로 쓰는 편이 싸다.

반대로 대화가 살아 있으면 도구는 부차적이다. 예제 표를 스프레드시트에 쓰고 그것을 코드에서 읽어 돌려도 ATDD 다. 문법이 아니라 "예제로 합의했고, 그 예제가 실행된다"가 조건이다.

어느 계층에 붙일 것인가

인수 테스트를 전부 UI 자동화로 붙이면 느리고 깨진다. 규칙 검증은 가능한 한 아래에서 한다.

계층적합한 시나리오주의
도메인·서비스 계층계산 규칙, 상태 전이, 검증 로직대부분의 인수 기준이 여기서 검증된다
API 계층권한, 응답 계약, 오류 코드계약 테스트와 역할이 겹치지 않게
UI 계층화면을 거쳐야 의미가 있는 흐름 1~2개"대표 경로"만. 규칙 검증을 여기 두지 않는다

레슨 1에서 본 UAT 는 사람이 하는 활동이고, 이 레슨의 자동화된 인수 테스트는 그 앞단에서 사람이 UAT 에서 확인할 필요가 없는 것을 미리 걸러 내는 장치 다. 둘은 대체 관계가 아니다.

실무에서 왜 필요한가

요구사항 오해로 생기는 재작업은 개발 비용에서 가장 비싼 항목 중 하나다. 그런데 오해는 회의에서 발견되지 않는다 — 추상 문장 앞에서는 모두가 동의하기 때문이다. ATDD 의 실질적 가치는 동의가 가짜였다는 사실을 개발 착수 전에 드러내는 것 이다. 배송비 예제의 세 번째 행 하나가, 코드가 나온 뒤에 발견됐다면 며칠짜리 재작업이었다.

QA 입장에서 더 중요한 것이 있다. ATDD 를 하는 팀에서 QA 는 테스트를 나중에 붙이는 사람에서 요구사항을 정하는 자리에 앉는 사람으로 옮겨 간다. 예제 매핑에서 빨강 카드를 가장 많이 뽑는 역할이 보통 테스터다. 결함을 찾는 능력과 모호함을 찾는 능력은 같은 근육이고, ATDD 는 그 근육을 개발 전에 쓰게 한다.

채용시장에서의 위치

국내 공고에서 "BDD/ATDD 경험", "Cucumber·SpecFlow 활용", "인수 기준 정의" 같은 문구는 주로 플랫폼·커머스·핀테크의 QA 엔지니어·SDET 공고에 나온다. 문제는 이 문구를 쓴 조직의 상당수가 실제로는 5번 실패 패턴에 있다 는 점이다. 면접에서 "Gherkin 써 봤습니다"는 변별력이 없다.

변별력은 이런 답에서 나온다. "예제 매핑을 도입해 리파인먼트에서 빨강 카드가 3개 이상이면 스프린트에 넣지 않는 규칙을 만들었다", "feature 파일을 규칙 단위로 재편하고 중복 200개를 40개로 줄였다", "UI 로 붙어 있던 인수 테스트를 서비스 계층으로 내려 실행 시간을 줄였다." 전부 도구가 아니라 판단 에 관한 답이다.

자격증 축에서는 ISTQB CTFL-AT(Agile Tester)가 ATDD·예제 기반 명세를 직접 다루고, CTFL 의 협업 기반 테스트 접근법 항목과도 겹친다. 다만 앞 문단의 답을 갖고 있지 않으면 자격증만으로는 같은 질문에서 막힌다.

실습 과제

과제 1 — 예제 매핑 세션 (25분)

다음 스토리로 예제 매핑을 진행한다. 혼자 하더라도 4색 카드(규칙·예제·질문) 구분은 지킨다.

스토리 — 회원은 주문한 상품을 반품 신청할 수 있다.

알려진 것: 배송 완료 후 7일 이내에만 신청 가능. 단순 변심은 배송비를 회원이 부담한다. 상품 불량은 판매자가 부담한다. 일부 카테고리(식품·속옷)는 반품 불가.

산출물은 규칙 카드 목록, 규칙별 예제 2개 이상, 질문 카드 목록이다. 끝난 뒤 본문의 종료 판정 세 가지로 이 스토리의 상태를 진단한다 — 착수 가능한가, 쪼개야 하는가, 질문부터 해소해야 하는가.

과제 2 — 시나리오 고치기 (20분)

다음 시나리오를 본문의 기준에 맞게 고쳐 쓴다. 고친 뒤 무엇을 왜 바꿨는지 를 항목별로 적는다.

Scenario: 반품 테스트
  Given 사용자가 로그인 페이지에 접속한다
  And "user01" / "pass01" 로 로그인한다
  And 마이페이지 메뉴를 클릭한다
  And 주문내역 탭을 클릭한다
  When 주문번호 20260901-001 의 반품신청 버튼을 누른다
  And 사유 선택 드롭다운에서 "단순변심" 을 고른다
  And 확인 버튼을 누른다
  Then 반품이 정상적으로 접수된다
  And 화면에 메시지가 표시된다

과제 3 — 예제 표 만들기 (20분)

과제 1의 규칙 중 배송비 부담 주체 규칙 하나를 골라 Scenario Outline 과 Examples 표로 쓴다. 조건은 다음과 같다.

  • 행은 8개를 넘기지 않는다
  • 경계값(7일째 / 8일째)을 반드시 포함한다
  • 반품 불가 카테고리 케이스를 포함한다
  • 표를 채우다 답이 정해지지 않은 칸이 나오면 ? 로 두고 질문 목록에 올린다

마지막으로 이 표가 현업 담당자가 읽고 틀린 곳을 짚을 수 있는 문서인지 스스로 판정한다.

자가 체크리스트

  • ATDD 의 대화 → 예제 → 자동화 흐름과 각 단계의 산출물을 말할 수 있다
  • ATDD·BDD·예제 기반 명세의 강조점 차이를 설명할 수 있다
  • 추상 문장 대신 예제를 쓰면 왜 불일치가 드러나는지 사례로 설명할 수 있다
  • 예제 매핑을 4색 카드로 진행하고 종료 판정 세 가지를 적용할 수 있다
  • 나쁜 Given-When-Then 의 세 유형(조작 절차·복수 행위·관찰 불가)을 식별하고 고칠 수 있다
  • Scenario Outline 과 예제 표로 규칙을 압축하고, 조합 폭발을 피할 수 있다
  • 살아 있는 문서가 성립하는 조건 다섯 가지를 말할 수 있다
  • 어떤 팀이 ATDD 를 하는지 아닌지 판정하는 질문을 하나 제시할 수 있다
  • 인수 테스트를 UI·API·서비스 계층 중 어디에 붙일지 근거를 대고 정할 수 있다

흔한 실수

  • 대화 없이 예제부터 쓴다. 그러면 ATDD 가 아니라 테스트 케이스 작성이다. 예제의 가치는 만들어진 결과물이 아니라 만드는 과정의 질문에 있다.
  • Gherkin 을 UI 조작 스크립트로 쓴다. 버튼 이름이 바뀔 때마다 깨지고, 현업은 읽지 않는다. 규칙의 서술로 쓴다.
  • 한 시나리오에 행위 여러 개를 넣는다. 실패했을 때 무엇이 깨졌는지 알 수 없다. 한 시나리오 = 한 규칙.
  • Then 에 "정상적으로", "올바르게"를 쓴다. 판정 불가능한 검증은 통과해도 의미가 없다.
  • 예제 표를 조합 곱셈으로 채운다. 243행짜리 명세는 아무도 안 읽는다. 규칙을 설명하는 최소 집합으로 두고, 나머지는 자동화 계층 데이터로 내린다.
  • 예제 매핑에서 빨강 카드를 그 자리에서 해결하려 한다. 25분 워크숍이 두 시간이 된다. 담당자와 기한을 붙여 밖으로 보낸다.
  • feature 파일을 개발자만 읽고 고친다. 도구는 남고 목적은 사라진 상태다. 이 상태라면 Gherkin 레이어를 걷어내는 편이 싸다.
  • 모든 인수 테스트를 UI 자동화로 붙인다. 느리고 불안정해서 결국 꺼지고, 꺼진 순간 살아 있는 문서도 죽는다.

참고 자료

  • Cucumber Docs — Gherkin Reference — Given/When/Then, Scenario Outline, Examples 표의 공식 문법
  • Cucumber Docs — BDD — 발견·정제·자동화 3단계와 three amigos 설명
  • Example Mapping (Cucumber Blog) — 4색 카드 워크숍 원문
  • ISTQB Certified Tester Foundation Level Agile Tester (CTFL-AT) Syllabus — ATDD 와 예제 기반 명세가 실러버스에 놓인 위치. 최신판 원문 확인
  • 레슨 s1-m02-l02 — 테스트 가능한 요구사항 쓰기
  • 레슨 s1-m02-l04 — 인수 기준(Acceptance Criteria)
  • 레슨 s2-m48-l03 — 리파인먼트 질문 설계와 스토리 슬라이싱 (예제 매핑이 여기서도 쓰인다)
  • 레슨 s2-m56-l01 — UAT 설계 (사람이 하는 인수와 자동화된 인수의 분담)
  • 레슨 s2-m56-l04 — RFP 요구사항을 인수 케이스로 옮기기

낯선 말 풀이

이 레슨에 나온 약어입니다. 본문에서도 처음 나올 때 점선으로 표시해 두었습니다 (제목과 링크 글자는 그대로 둡니다).

BDD — 행위 주도 개발
"어떤 상황에서 무엇을 하면 무엇이 된다"는 문장으로 요구사항을 적고, 그 문장을 그대로 시험으로 돌리는 방식.
UI — 사용자 인터페이스
사람이 직접 보고 누르는 부분 — 화면, 버튼, 입력창.
RFP — 제안 요청서
발주처가 "이런 걸 만들어 줄 수 있나" 하고 조건을 적어 내는 문서.
CI — 지속적 통합
코드를 올릴 때마다 자동으로 합쳐서 빌드하고 시험까지 돌리는 방식.
HTML — 하이퍼텍스트 표시 언어
웹 화면의 뼈대를 적는 글자 형식. 제목·문단·버튼 같은 역할을 꺾쇠 괄호로 표시한다.
API — 응용 프로그램 인터페이스
프로그램끼리 주고받는 창구. 사람이 화면 버튼을 누르는 대신, 프로그램이 정해진 주소로 요청을 보내 답을 받는다.
UAT — 인수 테스트
만든 쪽이 아니라 실제로 쓸 사람이 "이거면 받겠다"를 확인하는 마지막 시험.
QA — 품질보증
만든 것이 쓸 만한지 확인하고, 애초에 덜 망가지게 만드는 방법을 정하는 일. "테스트"는 그 일의 일부다.
SDET — 테스트 개발 엔지니어
시험을 코드로 만드는 사람. 개발과 QA 양쪽 일을 한다.
ISTQB — 국제 소프트웨어 테스팅 자격 위원회
테스터 자격 시험을 만들고 용어를 정리하는 국제 단체.
CTFL — 기초 등급 테스터 자격
테스터 자격의 가장 기초 단계. 용어와 기본 기법을 다룬다.

용어집 전체 보기