--- id: wiki-2026-0508-test-driven-development title: Test-Driven Development category: 10_Wiki/Topics status: verified canonical_id: self aliases: [TDD, Red-Green-Refactor, test first] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [tdd, testing, software-engineering, ai-aided] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: python framework: pytest --- # Test-Driven Development ## 매 한 줄 > **"매 Red → Green → Refactor 매 fail-first feedback loop"**. Kent Beck (Extreme Programming, ~2003) origin. 2026 매 AI-pair (Claude Code, Cursor) 의 default mode — agent의 test 먼저 generate 후 implementation 의 iterate. ## 매 핵심 ### 매 Cycle 1. **Red**: 매 failing test 의 write (no impl yet). 2. **Green**: 매 minimum code 의 test 의 pass. 3. **Refactor**: 매 clean up, 매 test still green. ### 매 Levels - **Unit**: pure function, 1 class. - **Integration**: 매 DB / network boundary. - **Acceptance / E2E**: 매 user flow. ### 매 vs BDD - TDD: developer-facing, 매 method-level. - BDD: stakeholder-facing, 매 Given-When-Then, Cucumber/Behave. ### 매 응용 1. Greenfield library — 매 API design 의 test 의 drive. 2. Bug fix — 매 reproducing test 먼저 write. 3. AI agent — 매 spec → test → impl 매 deterministic loop. ## 💻 패턴 ### Pytest red-green-refactor ```python # tests/test_pricing.py import pytest from pricing import discount_price def test_no_discount_for_zero_qty(): assert discount_price(100, qty=0) == 100 def test_10pct_discount_at_qty_10(): assert discount_price(100, qty=10) == 90.0 ``` ```python # pricing.py — minimum impl after red def discount_price(price: float, qty: int) -> float: if qty >= 10: return price * 0.9 return price ``` ### Parametrize ```python @pytest.mark.parametrize("qty,expected", [ (0, 100), (1, 100), (9, 100), (10, 90), (50, 90), (100, 80), ]) def test_discount_table(qty, expected): assert discount_price(100, qty=qty) == expected ``` ### Fixture + integration test ```python @pytest.fixture def db(): conn = sqlite3.connect(":memory:") conn.execute("CREATE TABLE orders (id INT, total REAL)") yield conn conn.close() def test_save_order(db): save_order(db, id=1, total=99.0) row = db.execute("SELECT total FROM orders WHERE id=1").fetchone() assert row[0] == 99.0 ``` ### Property-based (Hypothesis) ```python from hypothesis import given, strategies as st @given(st.floats(min_value=0, max_value=1e6), st.integers(min_value=0, max_value=1000)) def test_discount_never_exceeds_price(price, qty): assert discount_price(price, qty) <= price ``` ### TypeScript / Vitest ```typescript import { test, expect } from 'vitest'; import { discountPrice } from './pricing'; test('10% discount at qty 10', () => { expect(discountPrice(100, 10)).toBeCloseTo(90); }); ``` ### AI-aided TDD loop (2026) ```bash # .claude/commands/tdd.md # 1. Write failing test for: $ARGUMENTS # 2. Run pytest (expect red) # 3. Implement minimum code to pass # 4. Run pytest (expect green) # 5. Refactor; ensure still green # 6. Open PR ``` ```python # Claude Code automated loop pseudocode while not all_green: test = agent.generate_test(spec) write_file(test) run_pytest() # expect FAIL impl = agent.generate_impl_to_pass(test) write_file(impl) if run_pytest().passed: agent.refactor() ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | 매 pure function | TDD strict | | 매 UI tweak | Snapshot + visual diff (TDD overkill) | | 매 spike / prototype | Skip TDD, 매 throw away | | 매 bug fix | 매 reproducing test 먼저 | | 매 AI agent task | Test-first prompt — 매 verifiable | **기본값**: 매 TDD for business logic + libraries. 매 visual / experimental code 매 skip. ## 🔗 Graph - 변형: [[BDD]] · [[Property-Based Testing]] · [[Mutation Testing]] - 응용: [[Refactoring_Best_Practices|Refactoring]] - Adjacent: [[121_pytest_기본기|pytest]] · [[Hypothesis]] ## 🤖 LLM 활용 **언제**: 매 test generation (Claude Code "write tests for X"). 매 stub from spec. 매 reproducing-test from bug report. **언제 X**: 매 LLM의 hallucinate API → 매 test의 wrong. 매 always run + verify red→green. ## ❌ 안티패턴 - **Test after**: 매 not TDD; 매 confirms current code, 매 design 의 X drive. - **Mock everything**: 매 test의 verify nothing real. - **Brittle tests**: 매 implementation detail 의 lock — refactor breaks. - **Skipping refactor step**: 매 code rot. - **AI-generated test without running**: 매 false-green. ## 🧪 검증 / 중복 - Verified (Kent Beck "TDD by Example" 2003; Anthropic Claude Code TDD docs 2026). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — TDD red-green-refactor + property-based + AI agent loop |