{
    "slug": "test_driven_development",
    "term": "Test-Driven Development (TDD)",
    "category": "testing",
    "difficulty": "intermediate",
    "short": "A development practice where tests are written before production code, driving design through the Red-Green-Refactor cycle.",
    "long": "TDD follows a tight cycle: (1) write a failing test (Red), (2) write the minimum code to make it pass (Green), (3) refactor for quality while keeping tests green. Writing tests first forces clarity about requirements before implementation, produces naturally testable code (small, focused, with injected dependencies), and creates a comprehensive test suite as a by-product. TDD is a design activity as much as a testing activity — the pain of writing tests signals design problems. Outside-in TDD (starting from integration/acceptance tests) is called ATDD or BDD.",
    "aliases": [
        "TDD",
        "test-first development",
        "red-green-refactor"
    ],
    "tags": [
        "testing",
        "quality",
        "workflow",
        "refactoring"
    ],
    "misconception": "TDD means writing tests before every line of code, forever. TDD is a design technique — the tests drive you toward loosely coupled, testable code. Many experienced practitioners use it selectively for complex logic rather than mechanically for all code.",
    "why_it_matters": "TDD forces you to design the API of your code before implementing it — tests written first expose awkward interfaces immediately, when they are cheap to fix. The test suite that emerges is comprehensive by construction, not bolted on after.",
    "common_mistakes": [
        "Writing all tests first, then all implementation — TDD is red/green/refactor per small cycle, not a waterfall.",
        "Skipping the refactor step — without it TDD produces working but messy code.",
        "Writing tests that are too large — each cycle should test one specific behaviour.",
        "Abandoning TDD when time pressure hits — this is exactly when having tests matters most."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "unit_testing",
        "refactoring",
        "dependency_injection"
    ],
    "prerequisites": [
        "unit_testing",
        "mocking_best_practices",
        "refactoring"
    ],
    "refs": [
        "https://martinfowler.com/bliki/TestDrivenDevelopment.html"
    ],
    "bad_code": "// Test-last approach — code written first, then retrofitted with tests:\nclass UserService {\n    public function create(array $data): User {\n        // 100 lines of code written without tests\n        // Now write tests that 'fit' the existing code\n        // Tests describe implementation, not behaviour\n    }\n}\n// TDD: test first → drives minimal implementation → refactor safely",
    "good_code": "// RED: write a failing test first\npublic function test_discount_applied_for_vip(): void {\n    $pricing = new PricingService();\n    $price   = $pricing->calculate(product: $product, customer: $vip);\n    $this->assertEquals(90.00, $price); // FAILS — method doesn't exist yet\n}\n\n// GREEN: write the minimum code to pass\nclass PricingService {\n    public function calculate(Product $product, Customer $customer): float {\n        $price = $product->basePrice;\n        if ($customer->isVip()) $price *= 0.9;\n        return $price;\n    }\n}\n\n// REFACTOR: clean up while tests stay green",
    "quick_fix": "Write a failing test first, then write the minimum code to make it pass, then refactor — the test defines the API before the implementation exists",
    "severity": "info",
    "effort": "high",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/test_driven_development",
        "html_url": "https://codeclaritylab.com/glossary/test_driven_development",
        "json_url": "https://codeclaritylab.com/glossary/test_driven_development.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Test-Driven Development (TDD)](https://codeclaritylab.com/glossary/test_driven_development) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/test_driven_development"
            }
        }
    }
}