Applies TDD workflow to development. Use when implementing features, fixing bugs, or refactoring with test-first approach. Detects AI anti-patterns.
Scanned 2/10/2026
Install via CLI
openskills install ssiumha/dots---
name: tdd-practices
description: Applies TDD workflow to development. Use when implementing features, fixing bugs, or refactoring with test-first approach. Detects AI anti-patterns.
---
# TDD Practices
## Phase 1: TDD 세션 시작
새 기능이나 수정 작업 시작 시:
1. **요구사항 파악**
- 사용자가 요청한 기능을 명확히 이해
- 모호한 부분은 사용자에게 질문
2. **테스트 리스트 작성**
- 구현에 필요한 모든 테스트 케이스 나열
- 단순한 것부터 복잡한 순서로 정렬
- 사용자에게 목록 보여주고 확인받기
- 예: "다음 테스트들을 순서대로 진행하겠습니다: 1) ..., 2) ..., 3) ..."
3. **Baseline 확인**
- 기존 테스트 전체 실행
- 모두 통과하는지 확인
- 실패하는 테스트가 있다면 먼저 수정
4. **Phase 2 (RED)로 진행**
---
## Phase 2: RED - 실패하는 테스트 작성
테스트 리스트의 각 항목에 대해:
1. **작고 구체적인 테스트 하나 작성**
- 한 번에 하나의 동작만 검증
- 테스트 이름은 의도를 명확히 표현
- AAA 패턴 권장 (Arrange-Act-Assert)
- ✨ **테스트 작성 = 설계 활동**: 테스트하기 쉬운 인터페이스를 설계
- 부작용 최소화
- 의존성 명시적으로 표현
- 입력과 출력이 명확한 구조
2. **테스트 실행**
- 작성한 테스트만 먼저 실행
- 실패 메시지와 이유 확인
3. **올바른 이유로 실패하는지 검증**
- ⚠️ **테스트가 즉시 통과**: 이미 구현이 존재함, 다른 테스트 선택
- ⚠️ **테스트가 실행 안 됨**: 문법 오류, 진행 전 수정 필요
- ✅ **예상한 이유로 실패**: 정상, 다음 단계 진행
4. **실패 출력을 사용자에게 보여주기**
- 어떤 테스트가 실패했는지
- 왜 실패했는지 (예상값 vs 실제값)
5. **Phase 3 (GREEN)으로 진행**
---
## Phase 3: GREEN - 최소 구현
테스트를 통과시키기 위해:
1. **가장 단순한 코드 작성**
- 하드코딩 허용 (Fake It 전략)
- 정말 단순하고 명백한 경우에만 일반화된 구현
- **요청하지 않은 기능 절대 추가 금지** ⚠️
2. **허용되는 전략**
- **Fake It**: 하드코딩된 값 반환 (나중에 삼각측량으로 일반화)
- **Obvious Implementation**: 구현이 정말 명백한 경우
- **Triangulation**: 여러 테스트로 일반화 유도
→ ✨ 여러 테스트를 통과시키다 보면 자연스럽게 범용적 설계가 도출됨
3. **테스트 실행 → 통과 확인**
- 방금 작성한 테스트 실행
- 통과하는지 확인
4. **전체 테스트 실행 → 회귀 없음 확인**
- 기존 테스트들이 여전히 통과하는지 확인
- 회귀가 발생했다면 즉시 수정
5. **통과 출력을 사용자에게 보여주기**
6. **Phase 4 (REFACTOR)로 진행**
### GREEN 단계의 AI Red Flags 🚨
다음 징후 발견 시 즉시 중단하고 사용자에게 보고:
- 🚨 **현재 테스트에 없는 기능 추가**
- 예: 로그인 테스트인데 관리자 체크, 로깅 추가
- 🚨 **하드코딩으로 충분한데 반복문/조건문 사용**
- 첫 테스트에서는 하드코딩이 정상
- 🚨 **테스트 수정/삭제로 통과 시도**
- 테스트가 틀렸다면 사용자 확인 필요
- 🚨 **조기 최적화**
- 캐싱, 성능 최적화는 요청받지 않았다면 금지
---
## Phase 4: REFACTOR - 동작 변경 없이 개선
**핵심 원칙: 구조 변경과 기능 변경을 절대 섞지 말 것**
테스트가 모두 통과한 후:
1. **코드 냄새 식별**
- 중복 코드 (Copy & Paste)
- 불명확한 변수/함수 이름
- 긴 함수
- 복잡한 조건문
- ✨ **테스트하기 어려운 코드** (설계 재고 신호):
- 부작용이 많거나 의존성이 강하게 결합된 코드
- 단일 책임 원칙(SRP) 위반
- 테스트 작성이 어렵다면 → 함수 쪼개기, 의존성 주입 고려
2. **한 번에 하나의 리팩토링만 적용**
- Extract Method (메서드 추출)
- Rename (이름 변경)
- Remove Duplication (중복 제거)
- Inline (불필요한 간접 참조 제거)
3. **각 리팩토링 후 즉시 테스트 실행**
- 모든 테스트가 여전히 통과하는지 확인
- 실패 시 → 리팩토링 되돌리고 다른 방법 시도
4. **리팩토링이 끝나면 커밋**
- 깨끗한 상태로 유지
### REFACTOR 단계에서 절대 금지 ❌
- ❌ **새 기능 추가**: 기능은 다음 RED-GREEN 사이클에서
- ❌ **테스트 기댓값 변경**: 동작 변경의 증거
- ❌ **리팩토링과 기능 변경 혼합**: 별도 커밋으로 분리
- ❌ **테스트 통과를 위한 코드 수정**: REFACTOR는 이미 통과한 상태
### REFACTOR 중 테스트 실패 시
테스트가 실패했다면:
- 리팩토링이 아니라 동작 변경을 했다는 증거
- 즉시 되돌리기
- 더 작은 단위로 리팩토링 시도
5. **Phase 5로 진행**
---
## Phase 5: 반복 또는 완료
리팩토링 후:
1. **테스트 리스트로 돌아가기**
- 완료한 테스트 체크
- 남은 테스트 확인
2. **다음 단계 결정**
- 남은 테스트 있음 → **Phase 2 (RED)로 돌아가기**
- 모든 테스트 완료 → **완료 조건 확인**
3. **완료 조건 확인**
- ✅ 모든 테스트 통과
- ✅ 중복 코드 제거됨
- ✅ 의도가 명확함 (이름, 구조)
- ✅ 예상한 모든 케이스 커버
4. **필요 시 문서 업데이트**
- 새 기능에 대한 설명
- API 변경사항 기록
---
## 예시
### 예시 1: Fake It에서 일반화
**첫 번째 테스트 + 구현 (Fake It)**:
```python
def test_add():
assert add(2, 3) == 5
def add(a, b):
return 5 # 하드코딩 OK
```
**두 번째 테스트 → 일반화 강제**:
```python
def test_add_different():
assert add(1, 1) == 2 # 실패: assert 5 == 2
# 일반화된 구현
def add(a, b):
return a + b
```
전체 테스트 실행 → 모두 통과 ✓
---
### 예시 2: AI Red Flag 감지
**테스트**:
```python
def test_login():
assert login("user", "pass") == True
```
**⚠️ AI가 생성한 코드 (나쁨)**:
```python
def login(username, password):
check_admin_privileges(username) # 🚨 요청 안 함
log_access(username) # 🚨 요청 안 함
send_notification(username) # 🚨 요청 안 함
return True
```
**조치**: 즉시 중단하고 사용자에게 보고
```
⚠️ AI Red Flag 감지:
현재 테스트는 True 반환만 검증합니다.
AI가 요청하지 않은 기능들을 추가하려 합니다:
- 관리자 권한 체크
- 접근 로깅
- 알림 전송
GREEN 단계에서는 테스트 통과에 필요한 최소 코드만 작성해야 합니다.
진행 방법을 선택해주세요:
1. Fake It으로 단순히 True 반환 (권장)
2. 추가 기능을 테스트 리스트에 추가하고 순차 진행
```
**✅ 올바른 코드**:
```python
def login(username, password):
return True # Fake It OK
```
---
상세 참조는 [REFERENCE.md](./REFERENCE.md)를 확인하세요.
No comments yet. Be the first to comment!