행위 주도 개발 BDD(Behavior-Driven Development) 이해하기

1. BDD 개념 이해하기
BDD, 즉 Behavior-Driven Development는 한국어로 행위 주도 개발이라고 합니다.
BDD는 단순히 테스트 코드를 작성하는 방법이 아닙니다.
사용자의 행동과 비즈니스 요구사항을 중심으로 기능을 정의하고, 이를 기준으로 개발과 검증을 진행하는 방식입니다.
일반적인 개발 과정에서는 요구사항이 문서로 전달되고, 개발자가 이를 해석해 기능을 구현합니다.
요구사항 작성
↓
개발자 해석
↓
기능 구현
↓
테스트 작성
↓
QA 검증
이 방식은 익숙하지만, 다음과 같은 문제가 자주 발생합니다.
▸ 기획자가 의도한 요구사항과 개발자가 이해한 내용이 다를 수 있다.
▸ 테스트 코드는 있지만 비즈니스 관점의 검증 내용이 드러나지 않는다.
▸ QA 단계에서 기대 동작과 실제 구현의 차이가 뒤늦게 발견된다.
▸ 개발자, 기획자, QA가 서로 다른 언어로 기능을 설명한다.
BDD는 이러한 문제를 줄이기 위해 기능을 다음 질문으로 정리합니다.
▸ 사용자가 어떤 상황에서
▸ 어떤 행동을 했을 때
▸ 시스템은 어떤 결과를 보여줘야 하는가?
즉, BDD의 핵심은 코드가 어떻게 동작하는가보다 사용자 관점에서 어떤 행동과 결과가 필요한가를 먼저 정의하는 것입니다.
2. Given-When-Then으로 보는 BDD 작성 방식
BDD에서 가장 많이 사용하는 시나리오 작성 방식은 Given-When-Then입니다.
| 구분 | 의미 | 예시 |
| Given | 주어진 상황 | 사용자가 로그인한 상태이다 |
| When | 사용자의 행동 | 장바구니에 상품을 추가한다 |
| Then | 기대 결과 | 장바구니 상품 개수가 1 증가한다 |
✔️ 이를 하나의 문장 구조로 보면 다음과 같습니다.
Given: 어떤 상황에서
When: 어떤 행동을 하면
Then: 어떤 결과가 나와야 한다
예를 들어 장바구니 기능은 다음과 같이 작성할 수 있습니다.
Feature: 장바구니 상품 추가
Scenario: 로그인한 사용자가 상품을 장바구니에 추가한다
Given 사용자가 로그인한 상태이고
And 상품 상세 페이지에 접속해 있다
When 사용자가 장바구니 담기 버튼을 클릭하면
Then 장바구니에 해당 상품이 추가된다
And 장바구니 상품 개수가 1 증가한다
이 시나리오는 개발자뿐만 아니라 기획자와 QA도 쉽게 이해할 수 있습니다.
BDD 시나리오를 작성할 때 중요한 점은 구현 세부사항보다 비즈니스 결과를 표현하는 것입니다.
✔️ 좋지 않은 예시는 다음과 같습니다.
Scenario: 로그인 버튼 클릭
Given 사용자가 input[name=email]에 이메일을 입력했다
And 사용자가 input[name=password]에 비밀번호를 입력했다
When 사용자가 button.login-submit을 클릭한다
Then div.user-profile이 화면에 표시된다
이 방식은 CSS Selector나 HTML 구조에 강하게 의존합니다.
UI 구조가 바뀌면 시나리오도 함께 수정해야 합니다.
✔️ 더 좋은 방식은 다음과 같습니다.
Scenario: 사용자가 올바른 계정 정보로 로그인한다
Given 사용자가 로그인 페이지에 있다
When 사용자가 올바른 이메일과 비밀번호로 로그인하면
Then 사용자는 내 정보 페이지로 이동한다
3. BDD에서 TDD로 이어지는 실무 개발 흐름
BDD와 TDD는 서로 대체 관계가 아닙니다.
BDD가 사용자 행동과 비즈니스 요구사항을 시나리오로 정리한다면, TDD는 그 시나리오를 만족하기 위한 구현 단위의 테스트를 작성하고 코드를 설계하는 방식입니다.
흐름은 다음과 같습니다.
요구사항 논의
↓
BDD 시나리오 작성
↓
인수 조건 정의
↓
TDD 테스트 작성
↓
최소 구현
↓
리팩터링
↓
BDD 시나리오 기준 검증
✔️ 요구사항은 다음과 같습니다.
사용자는 비밀번호가 8자 이상일 때만 회원가입을 진행할 수 있다.
✔️ 먼저 BDD로 사용자 시나리오를 작성합니다.
Feature: 회원가입 비밀번호 검증
Scenario: 사용자가 유효한 비밀번호를 입력한다
Given 사용자가 회원가입 페이지에 있다
When 사용자가 8자 이상의 비밀번호를 입력하면
Then 회원가입을 진행할 수 있다
Scenario: 사용자가 8자 미만의 비밀번호를 입력한다
Given 사용자가 회원가입 페이지에 있다
When 사용자가 8자 미만의 비밀번호를 입력하면
Then 회원가입을 진행할 수 없다
And 비밀번호는 8자 이상이어야 한다는 메시지를 보여준다
이 시나리오는 개발자가 바로 구현을 시작하기 위한 코드가 아닙니다.
먼저 기획자, QA, 개발자가 같은 기준으로 요구사항을 이해하기 위한 인수 조건입니다.
✔️ 이제 개발자는 이 인수 조건을 만족하기 위해 구현 단위의 테스트를 작성합니다.
describe('isValidPassword', () => {
test('비밀번호가 8자 이상이면 true를 반환한다', () => {
expect(isValidPassword('12345678')).toBe(true);
});
test('비밀번호가 8자 미만이면 false를 반환한다', () => {
expect(isValidPassword('1234567')).toBe(false);
});
test('비밀번호가 비어 있으면 false를 반환한다', () => {
expect(isValidPassword('')).toBe(false);
});
});
여기서 TDD는 작은 단위의 구현을 이끄는 역할을 합니다.
BDD 시나리오가 다음을 정의했다면:
사용자는 8자 이상의 비밀번호를 입력해야 회원가입을 진행할 수 있다.
TDD 테스트는 이를 코드 단위로 더 구체화합니다.
비밀번호가 8자 이상이면 true
비밀번호가 8자 미만이면 false
비밀번호가 비어 있으면 false
✔️ 그다음 TDD 사이클에 따라 구현합니다.
Red: 실패하는 테스트 작성
↓
Green: 테스트를 통과하는 최소 코드 작성
↓
Refactor: 동작을 유지하면서 코드 개선
구현 코드는 다음처럼 단순하게 시작할 수 있습니다.
function isValidPassword(password) {
if (!password) {
return false;
}
return password.length >= 8;
}
✔️ 마지막으로 BDD 시나리오 기준으로 전체 흐름을 검증합니다.
TDD 테스트 통과
↓
Step Definition 연결
↓
BDD 시나리오 실행
↓
인수 조건 충족 여부 확인
✔️ 정리하면 다음과 같습니다.
BDD: 사용자의 행동과 기대 결과를 정의한다.
TDD: 그 기대 결과를 만족하는 구현을 테스트로 설계한다.
BDD 검증: 실제 기능이 인수 조건을 만족하는지 확인한다.
4. BDD를 실무에 적용할 때의 기준과 주의점
BDD의 핵심 목적은 테스트 코드를 많이 작성하는 것이 아니라, 비즈니스 요구사항을 사용자 행동 중심으로 명확히 정의하고 팀이 같은 기준으로 기능을 이해하는 것입니다.
따라서 실무에서는 BDD를 적용할 기능과 그렇지 않은 기능을 구분하는 것이 중요합니다.
사용자가 어떤 상태에서 어떤 행동을 했을 때, 시스템이 어떤 결과를 제공해야 하는지 명확히 정의해야 합니다.
✔️ BDD 적용이 특히 효과적인 경우는 다음과 같습니다.
| 기준 | 설명 |
| 비즈니스 규칙이 복잡한 기능 | 쿠폰, 결제, 정산처럼 조건과 예외가 많은 기능 |
| 여러 이해관계자가 함께 검토해야 하는 기능 | 기획자, QA, 개발자, 비즈니스 담당자가 함께 확인해야 하는 기능 |
| 사용자 흐름이 중요한 기능 | 회원가입, 주문, 환불처럼 단계별 흐름이 중요한 기능 |
| 인수 조건이 명확해야 하는 기능 | QA나 PO가 “완료” 여부를 판단해야 하는 기능 |
| 장애 영향이 큰 핵심 기능 | 결제, 주문, 권한처럼 장애 발생 시 비즈니스 영향이 큰 기능 |
즉, BDD는 “이 기능이 의도한 비즈니스 결과를 만족하는가?”를 명확히 검증해야 하는 곳에 적합합니다.
✔️ BDD 도입 시 추천 순서
BDD를 처음 도입할 때는 도구부터 선택하기보다, 먼저 팀이 Given-When-Then 방식으로 요구사항을 정리하는 습관을 들이는 것이 좋습니다.
추천 흐름은 다음과 같습니다.
1. 핵심 비즈니스 흐름을 하나 선택한다.
2. 요구사항을 Given-When-Then 형식으로 작성한다.
3. 성공 케이스와 실패 케이스를 분리한다.
4. 기획자, QA, 개발자가 함께 시나리오를 리뷰한다.
5. 자동화 가치가 높은 시나리오만 테스트로 연결한다.
6. 반복되는 Step Definition을 공통화한다.
7. CI/CD에서 주요 BDD 시나리오를 회귀 테스트로 실행한다.
✔️ 좋은 BDD 시나리오 작성 기준
BDD 시나리오는 자연어처럼 보이지만, 아무 문장이나 나열하면 유지보수가 어려워집니다.
| 기준 | 설명 |
| 사용자 관점으로 작성한다 | 내부 구현보다 사용자의 행동과 목적을 중심으로 표현합니다. |
| 하나의 시나리오는 하나의 행동을 검증한다 | 여러 동작을 한 시나리오에 넣으면 실패 원인을 파악하기 어렵습니다. |
| Then에는 관찰 가능한 결과를 쓴다 | DB 값 변경 같은 내부 상태보다 사용자나 시스템이 확인할 수 있는 결과를 씁니다. |
| 구현 세부사항에 의존하지 않는다 | CSS Selector, 버튼 ID, API 내부 구조 같은 표현은 피합니다. |
| Given이 지나치게 길어지지 않게 한다 | 사전 조건이 너무 많으면 시나리오의 핵심이 흐려집니다. |
| 비즈니스 용어를 일관되게 사용한다 | 팀이 합의한 용어로 작성해야 오해가 줄어듭니다. |
✔️ BDD와 TDD를 함께 사용할 때의 역할 분리
BDD를 TDD와 함께 사용할 때는 역할을 명확히 나누는 것이 중요합니다.
| 구분 | 역할 |
| BDD | 사용자 행동, 비즈니스 시나리오, 인수 조건 정의 |
| TDD | 구현 단위 테스트 작성, 설계 피드백, 최소 구현 |
| 단위 테스트 | 함수, 메서드, 클래스 단위의 빠른 검증 |
| 통합/E2E 테스트 | 실제 시스템 흐름과 외부 연동 검증 |
BDD 시나리오가 너무 세부 구현까지 검증하려고 하면 테스트가 무거워지고 변경에 취약해집니다.
반대로 TDD 테스트가 비즈니스 시나리오 전체를 설명하려고 하면 테스트 의도가 흐려질 수 있습니다.
BDD: 무엇을 만족해야 하는가?
TDD: 그것을 어떻게 안정적으로 구현할 것인가?
즉, BDD는 개발 방향을 정하고, TDD는 구현을 이끄는 역할을 합니다.
※ 게시된 글 및 이미지 중 일부는 AI 도구의 도움을 받아 생성되거나 다듬어졌습니다.
'5. IT기술노트 > 인프라&개발' 카테고리의 다른 글
| Redis의 기술적 특징과 고성능 데이터 처리 구조 (0) | 2026.05.27 |
|---|---|
| V모델로 이해하는 테스트 레벨과 테스트 방법 (0) | 2026.05.12 |
| Latency Numbers로 설계하는 백엔드 아키텍처 (0) | 2026.05.05 |
| 테스트 주도 개발 TDD(Test-Driven Development) 이해하기 (0) | 2026.05.05 |
| CQRS 개념과 Read-Your-Own-Writes 해결 전략 (0) | 2026.02.09 |