TDD, BDD, DDD, SDD: 소프트웨어 개발 방법론 비교
TDD, BDD, DDD, SDD 각 방법론의 핵심 개념, Red-Green-Refactor 사이클과 적용 시나리오
소프트웨어 개발 방법론의 핵심 패러다임을 정리한 문서. 각 방법론이 코드 품질, 비즈니스 가치, 아키텍처 설계에 미치는 영향을 다룬다.
TDD (Test Driven Development)
켄트 벡(Kent Beck)이 크라이슬러 종합 보상 시스템(C3) 프로젝트에서 익스트림 프로그래밍(XP)의 핵심 실천법으로 도입.
- 실패하는 자동화된 테스트를 작성하기 전에는 단 한 줄의 코드도 작성하지 않는다.
- 중복을 제거한다.
개발자에게 심리적 안정감과 확신을 심어주는 것이 목표. 실패하는 테스트를 먼저 작성하는 행위는 기능에 대한 **명확하고 실행 가능한 명세(specification)**를 정의하는 과정이다. YAGNI(You Ain't Gonna Need It) 원칙을 자연스럽게 따르게 된다.
Red-Green-Refactor 사이클
TDD의 핵심 메커니즘으로 짧고 반복적인 개발 주기를 통해 소프트웨어를 점진적으로 구축하고 개선하기 위한 피드백 루프.
| 단계 | 설명 | 핵심 |
|---|---|---|
| Red | 실패하는 테스트 작성. API 설계, 입력값, 기대 결과 등 명세를 미리 정의 | 테스트 시스템의 정상 동작 확인 |
| Green | 최소한의 코드로 테스트를 통과. 하드코딩이나 임시 코드 허용 | 기능적 요구사항 만족에 집중 |
| Refactoring | 기능 변경 없이 내부 구조 개선. 중복 제거, 가독성 향상, 설계 패턴 적용 | TDD가 설계 방법론으로 불리는 이유 |
아키텍처에 미치는 영향
- 진화적 설계(Evolutionary Design) 가능
- 테스트 코드 작성 제약 → 시스템을 작고 느슨하게 결합된 컴포넌트로 분리 유도
- 거대한 단일 함수 → 작은 함수로 분리, 외부 의존성 → DI 원칙 적용
BDD (Behavior Driven Development)
Dan North 창시. TDD에서 '무엇을 테스트해야 하는지'에 대한 어려움을 해결하기 위해 등장.
Test 용어 대신 Behavior, Example, Specification 같은 단어를 사용하여 비즈니스 관점으로 전환. 핵심 철학은 소프트웨어 개발이 기술적 구현이 아닌 비즈니스 목표를 달성하기 위한 협업과 소통의 과정이라는 것.
Gherkin DSL (Given - When - Then)
시스템의 행위를 자연어에 가까운 형태로 서술하는 도메인 특화 언어(DSL).
| 키워드 | 역할 |
|---|---|
| Feature | 개발 기능의 전반적 설명. 사용자 스토리 형식 (As a [역할], I want [기능], so that [혜택]) |
| Scenario | 기능이 가져야 할 구체적인 행위 예시 |
| Given | 시나리오 시작 전 초기 컨텍스트 (시스템 상태 설정) |
| When | 사용자의 행동이나 시스템 이벤트 |
| Then | 행위 이후 기대되는 결과나 상태 변화 검증 |
| And, But | Given/When/Then 구문 연결 |
Feature: 사용자 로그인
Scenario: 올바른 자격 증명으로 성공적으로 로그인
Given 사용자가 로그인 페이지에 있다
When 올바른 아이디와 비밀번호를 입력하고
And 로그인 버튼을 클릭하면
Then 사용자는 대시보드 페이지로 리디렉션되어야 한다거킨으로 작성된 명세는 **유비쿼터스 언어(Ubiquitous Language)**의 역할을 하며, 자동화된 테스트 코드로 직접 연결되어 **살아있는 문서(Living Documentation)**가 된다.
아키텍처에 미치는 영향: Outside-In 설계
- Outside-In 개발 방식 촉진: 시스템 바깥쪽 경계(API, UI)에서 안쪽으로 파고드는 접근
- 사용자 중심의 인터페이스: 외부 계약이 사용자 요구사항에 의해 직접 결정
- YAGNI 원칙 강화: 명시된 행위를 지원하는 데 필요한 코드만 작성
- 관심사의 분리: 헥사고날 아키텍처와 자연스럽게 부합
FastAPI & Pytest-BDD 실습
GitHub: https://github.com/Jonggkwan/BDD_FastAPI
BDD 접근법으로 FastAPI 결제 처리 기능 구현 예시:
- Feature 파일 작성 → 비즈니스 요구사항을 거킨으로 정의
- Step Definition → pytest-bdd로 각 단계를 파이썬 함수로 매핑
- 애플리케이션 코드 구현 → 시나리오를 통과시키기 위한 FastAPI 엔드포인트 작성
- 테스트 실행 및 확인 → 비즈니스 요구사항의 자동 검증
DDD (Domain-Driven Design)
2003년 Eric Evans 저술. SW 개발의 초점을 DB나 Framework 같은 기술적 관심사에서 Domain 자체로 옮기는 설계 철학.
복잡한 애플리케이션의 성공 여부는 기술적 정교함이 아니라, 비즈니스 도메인을 얼마나 깊이 이해하고 정확하게 모델링했느냐에 달려있다.
전략적 DDD 패턴
시스템 전체의 큰 그림을 그리고 복잡성을 여러 부분으로 나누는 데 초점.
| 패턴 | 설명 |
|---|---|
| Ubiquitous Language | 모든 참여자가 공유하는 단일하고 엄격한 언어. 회의, 문서, 코드에 동일하게 사용 |
| Bounded Context | 특정 도메인 모델이 일관성을 유지하며 적용되는 명시적인 경계 |
| Context Map | Bounded Context들의 관계를 시각적으로 표현하고 정의 |
Context Map의 주요 관계 패턴: 파트너십(Partnership), 공유 커널(Shared Kernel), 고객-공급자(Customer-Supplier), 안티커럽션 레이어(Anticorruption Layer)
전술적 DDD 패턴
| 패턴 | 설명 |
|---|---|
| Entity | 고유한 식별자(identity)에 의해 정의되는 객체. 속성은 변해도 식별자는 불변 |
| Value Object | 식별자 없이 속성 값으로만 정의되는 불변(immutable) 객체 |
| Aggregate | 관련 엔티티와 VO의 묶음. 데이터 변경의 일관성 보장 단위. Aggregate Root를 통해서만 접근 |
| Repository | 영속성(persistence) 메커니즘을 추상화. 도메인 로직과 인프라 분리 |
아키텍처에 미치는 영향
- Bounded Context → 마이크로서비스의 경계를 정의하는 이상적인 기준
- 전술적 패턴 → 클린 아키텍처/헥사고날 아키텍처의 계층에 부합
- 도메인 계층: 순수 비즈니스 로직 (Aggregate, Entity, Value Object)
- 애플리케이션 계층: 유스케이스 오케스트레이션
- 인프라스트럭처 계층: 외부 세계와의 상호작용 (API, DB, 메시지 큐)
콘웨이의 법칙(Conway's Law): "시스템을 설계하는 조직은 조직의 의사소통 구조를 빼닮은 구조의 디자인을 만들게 된다"
DDD는 도메인 중심의 커뮤니케이션 구조를 설계함으로써 콘웨이의 법칙을 유리하게 활용할 수 있게 한다.
GitHub: https://github.com/Jonggkwan/DDD_FastAPI
SDD (Spec-Driven Development)
API 명세(Specification)를 먼저 작성하고, 이를 기반으로 코드를 생성하는 방식. AI 기반 개발 도구와 결합하여 활용 가능.
방법론 비교
| 방법론 | 출발점 | 핵심 질문 | 주요 산출물 |
|---|---|---|---|
| TDD | 실패하는 테스트 | "이 코드가 올바르게 동작하는가?" | 테스트 커버리지, 리팩토링된 코드 |
| BDD | 비즈니스 시나리오 | "사용자에게 어떤 가치를 제공하는가?" | 살아있는 문서, 인수 테스트 |
| DDD | 도메인 모델 | "비즈니스를 어떻게 모델링할 것인가?" | 공유된 정신 모델, 바운디드 컨텍스트 |
| SDD | API 명세 | "어떤 인터페이스를 제공할 것인가?" | API 문서, 코드 생성 |
태그
#SoftwareEngineering #TDD #BDD #DDD #DesignMethodology