Use when adding new error messages to React, or seeing "unknown error code" warnings.
npx skills add raki-1203/claude-config --skill "tdd-guide"
Install specific skill from multi-skill repository
# Description
Test-Driven Development (TDD) specialist enforcing write-tests-first methodology. MUST USE when: fixing bugs (버그 수정), implementing new features (기능 구현), refactoring code, '/fix-issue' invoked, user mentions 'test', 'TDD', '테스트', '테스트 먼저'. Ensures 80%+ test coverage with RED-GREEN-REFACTOR cycle.
# SKILL.md
name: tdd-guide
description: "Test-Driven Development (TDD) specialist enforcing write-tests-first methodology. MUST USE when: fixing bugs (버그 수정), implementing new features (기능 구현), refactoring code, '/fix-issue' invoked, user mentions 'test', 'TDD', '테스트', '테스트 먼저'. Ensures 80%+ test coverage with RED-GREEN-REFACTOR cycle."
TDD Guide
Test-Driven Development specialist: 테스트 먼저, 코드 나중.
TDD Cycle: RED → GREEN → REFACTOR
1. RED - 실패하는 테스트 작성
2. GREEN - 테스트 통과하는 최소 코드
3. REFACTOR - 코드 정리 (테스트 유지)
Step 1: Write Test First (RED)
테스트가 먼저. 코드는 나중.
Bug Fix 예시
// 버그: "로그인 버튼이 비활성화 안됨"
describe('LoginButton', () => {
it('should be disabled when email is empty', () => {
render(<LoginButton email="" password="123" />)
expect(screen.getByRole('button')).toBeDisabled()
})
it('should be disabled when password is empty', () => {
render(<LoginButton email="[email protected]" password="" />)
expect(screen.getByRole('button')).toBeDisabled()
})
})
New Feature 예시
// 기능: "검색 결과 5개 반환"
describe('searchMarkets', () => {
it('returns 5 semantically similar markets', async () => {
const results = await searchMarkets('election')
expect(results).toHaveLength(5)
expect(results[0].similarity).toBeGreaterThan(0.8)
})
})
Step 2: Verify Test FAILS
# 테스트 실행 → 반드시 실패해야 함
npm test
# 또는
flutter test
# 또는
pytest
중요: 테스트가 통과하면 잘못된 테스트! 다시 작성.
Step 3: Write Minimal Code (GREEN)
테스트 통과하는 최소한의 코드만 작성
// 최소 구현
function LoginButton({ email, password }) {
const isDisabled = !email || !password
return <button disabled={isDisabled}>Login</button>
}
하지 말 것:
- 미래를 위한 코드 추가
- 관련 없는 리팩토링
- 최적화
Step 4: Verify Test PASSES
npm test
# ✅ All tests pass
Step 5: Refactor (IMPROVE)
테스트가 통과한 상태에서:
- 중복 제거
- 이름 개선
- 구조 정리
# 리팩토링 후 테스트 재실행
npm test
# ✅ Still passing
Step 6: Verify Coverage
npm test -- --coverage
# 또는
flutter test --coverage
# 또는
pytest --cov
목표: 80%+ coverage
Test Types (필수)
1. Unit Tests (항상 필수)
개별 함수/컴포넌트 테스트:
describe('calculateSimilarity', () => {
it('returns 1.0 for identical embeddings', () => {
const embedding = [0.1, 0.2, 0.3]
expect(calculateSimilarity(embedding, embedding)).toBe(1.0)
})
it('handles null gracefully', () => {
expect(() => calculateSimilarity(null, [])).toThrow()
})
})
2. Integration Tests (API/DB 있으면 필수)
describe('GET /api/users', () => {
it('returns 200 with valid results', async () => {
const response = await request(app).get('/api/users')
expect(response.status).toBe(200)
expect(response.body.users).toBeInstanceOf(Array)
})
it('returns 401 without auth', async () => {
const response = await request(app)
.get('/api/users')
.set('Authorization', '')
expect(response.status).toBe(401)
})
})
3. E2E Tests (중요 플로우만)
// Playwright
test('user can login', async ({ page }) => {
await page.goto('/login')
await page.fill('input[name="email"]', '[email protected]')
await page.fill('input[name="password"]', 'password')
await page.click('button[type="submit"]')
await expect(page).toHaveURL('/dashboard')
})
Edge Cases (반드시 테스트)
| Case | Example |
|---|---|
| Null/Undefined | input = null |
| Empty | input = "" or [] |
| Invalid Type | string instead of number |
| Boundary | 0, -1, MAX_INT |
| Error | Network failure, DB error |
| Special Chars | Unicode, emoji, SQL injection |
Mocking External Dependencies
Mock API/DB
jest.mock('@/lib/db', () => ({
query: jest.fn(() => Promise.resolve([
{ id: 1, name: 'Test' }
]))
}))
Mock HTTP
jest.mock('axios', () => ({
get: jest.fn(() => Promise.resolve({ data: mockData }))
}))
Quality Checklist
테스트 완료 전 확인:
- [ ] 모든 public 함수에 테스트
- [ ] Edge cases 커버 (null, empty, error)
- [ ] Error paths 테스트 (happy path만 X)
- [ ] Mocks 사용 (외부 의존성)
- [ ] 테스트 독립적 (순서 무관)
- [ ] 80%+ coverage
Anti-Patterns (하지 말 것)
❌ Implementation 테스트
// BAD: 내부 상태 테스트
expect(component.state.count).toBe(5)
✅ Behavior 테스트
// GOOD: 사용자가 보는 것 테스트
expect(screen.getByText('Count: 5')).toBeInTheDocument()
❌ 테스트 간 의존
// BAD: 이전 테스트에 의존
test('creates user', () => { /* ... */ })
test('updates same user', () => { /* 위 테스트 필요 */ })
✅ 독립적 테스트
// GOOD: 각 테스트에서 데이터 생성
test('updates user', () => {
const user = createTestUser()
// ...
})
Framework Commands
| Framework | Run Tests | Coverage |
|---|---|---|
| Jest | npm test |
npm test -- --coverage |
| Vitest | npm test |
npm test -- --coverage |
| Pytest | pytest |
pytest --cov |
| Flutter | flutter test |
flutter test --coverage |
| Go | go test ./... |
go test -cover ./... |
Integration with fix-issue
/fix-issue 68
│
├─ 이슈 분석
│
├─ TDD 적용 (이 skill)
│ ├─ 버그 재현 테스트 작성 (RED)
│ ├─ 테스트 실패 확인
│ ├─ 최소 수정 (GREEN)
│ ├─ 테스트 통과 확인
│ └─ 리팩토링 (REFACTOR)
│
└─ 커밋 + PR
Remember: 테스트 없이 코드 없다. 테스트가 안전망이다.
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.