Use when reasoning about Test-Driven Development as a design discipline rather than a workflow: the red-green-refactor cycle as a feedback loop, the difference between London-school (outside-in, interaction-heavy, mock-driven) and Detroit-school (inside-out, state-heavy, classicist) TDD, the role of TDD as a design tool (how tests pressure code into more decomposable shapes), the connection between TDD and emergent design, the boundary between TDD and prior-test-suites, why TDD's failure mode is not 'no tests' but 'tests that mirror implementation', and the empirical record of TDD's effects on defect density, design quality, and development velocity. Do NOT use for the strategy of what to test at which level (use testing-strategy), the construction of test doubles (use test-doubles-design), the discipline of LLM eval iteration (use eval-driven-development), or general-software process workflow (use the obra/superpowers test-driven-development workflow skill — this skill is the concept-shape complement).
TDD is design discipline through the test-writing lens. The unit of work is the red-green-refactor cycle: write one failing test for one increment of behavior (red), write the smallest production change that makes it pass (green), restructure the shape of both code and test while keeping all tests passing (refactor). Each cycle fits in a few minutes; long cycles indicate either insufficient test granularity or production complexity that should be decomposed. The test suite is the design pressure that shapes production code — writing tests first surfaces hard-to-test code at the moment when the underlying design discomfort (hard-to-use, hard-to-compose, hard-to-maintain) is still cheap to correct.
Replaces test-after-implementation with test-driven design pressure. Solves the problem that tests written after the code mirror the implementation rather than the desired behavior — they lock the current shape in place, fragment under refactor, and miss the design feedback that comes only from articulating what a unit should do before writing it. Industrial evidence (Nagappan et al. 2008 at Microsoft and IBM across four teams) shows TDD codebases have 40-90% lower defect density at 15-35% longer initial development time; Erdogmus et al. (2005), Janzen & Saiedian (2008), and Bissi et al. (2016) converge on the same direction. Replaces "tests as regression coverage" with "tests as design pressure that produces regression coverage as a side effect."
Distinct from testing-strategy, which owns the strategic question of what to test, at which level, with what evidence — strategy decides the surface, TDD prescribes the rhythm within it. Distinct from test-doubles-design, which owns mocks/stubs/fakes/spies as constructs — TDD's schools differ on how much test-doubles design matters to the practice (London heavily, Detroit lightly); the two compose. Distinct from eval-driven-development, the LLM analog where the unit of judgment is pass-rate over a sample rather than binary per-test pass/fail — both share the iteration-first-then-implement spirit but the math underneath differs. Distinct from refactor, which owns behavior-preserving structural change as a technique — TDD calls refactor as the third beat of red-green-refactor; refactor owns how to do it without breaking behavior. Distinct from the obra/superpowers TDD workflow skill on skills.sh, which is workflow-shape (process steps); this skill is concept-shape (the discipline's underlying mechanism). TDD is to code design what a piano teacher's metronome is to a student's playing — the rhythm is not the music, but it surfaces every uneven phrase, every rushed measure, every hesitation, in time to correct it before it ossifies into habit. The wrong mental model is that TDD is "writing tests first" as a procedural rule, where the tests are the point and the production code merely satisfies them. They are not the point. Tests are an artifact of doing design with a test-shaped tool; a team that "does TDD" by writing tests first without heeding the design pressure has the artifact without the practice, and will conclude TDD doesn't work because they will see only the cost (slower initial development) without the benefit (better-shaped code with lower defect density). Two adjacent misconceptions: that high coverage is the goal (coverage is a side effect; engineering tests to satisfy a coverage number Goodharts the discipline), and that the school doesn't matter (a practitioner who has not chosen London or Detroit has chosen by accident — the test suite's character, mock-rich vs state-rich, interaction-heavy vs state-heavy, reveals which school is in use whether the team named it or not).
Coverage
The design discipline of writing the test before the production code that satisfies it, using the test-writing pressure to shape the code's design, and applying the red-green-refactor cycle as the unit of work. Covers the cycle structure (red → green → refactor), the design-pressure mechanism that makes TDD a design discipline rather than just a test-first habit, the London/Detroit/Chicago school distinctions (mockist vs classicist, outside-in vs inside-out, interaction vs state), the relationship between TDD and emergent design, the empirical record (Nagappan 2008 at Microsoft/IBM and meta-analyses since), the boundary between TDD and BDD, and the failure modes (skipping refactor, ignoring design pressure, mock-heavy fragile tests, coverage-as-goal Goodharting).
Philosophy of the skill
TDD is design through the test-writing lens. Every test you sit down to write is a moment of design: what is this unit, what does it own, what does it delegate, what does its interface look like from the outside. The discomfort of writing a hard-to-test piece of code is the same discomfort that will eventually arrive as hard-to-use, hard-to-maintain, hard-to-compose code; TDD makes that discomfort visible at the moment when correcting it is cheap.
The tests are not the point. The tests are an artifact of doing design with a test-shaped tool. A team that "does TDD" by writing tests first without heeding the design pressure has the artifact without the practice; they will conclude TDD doesn't work because they will see only the cost (slower initial development) without the benefit (better-shaped code with lower defect density).
The schools matter. London and Detroit produce different code under the same red-green-refactor cycle, because they apply the design pressure to different surfaces. A practitioner who has not chosen a school has chosen by accident, and the test suite's character — interaction-heavy or state-heavy, mock-rich or mock-sparse, outside-in or inside-out — reveals which they chose without knowing.
The Cycle In Detail
Beat
Activity
Stop condition
Common mistake
Red
Write one failing test for one increment of desired behavior
The test compiles and fails for the right reason (not a syntax error)
Writing a passing test (no design pressure); writing many tests at once (loses the increment)
Green
Write the smallest production change that makes the test pass
The test passes; no other tests broke
Writing more than needed; "fake it till you make it" abandoned too early
Refactor
Improve the shape of both code and test while keeping all tests passing
The structure is cleaner; tests still pass
Skipping this beat; refactoring into bigger changes that break tests
Each cycle should fit in a few minutes — long cycles indicate either insufficient test granularity or production complexity that should be decomposed before continuing.
London School vs Detroit School — A Practical Comparison
Property
London (mockist, outside-in)
Detroit (classicist, inside-out)
Origin
Freeman & Pryce, GOOS (2009)
Beck, TDD by Example (2002)
Starting point
Acceptance test or service boundary
A single concrete unit
Test focus
Interactions (who called whom with what)
Observable state changes
Test doubles
Central — every new collaborator becomes a mock
Sparse — used only when needed (DB, external service)
Design pressure
On collaborator interfaces (the mocks shape them)
On units' responsibilities and state shape
Failure mode
Tests mirror implementation; refactor breaks them
State assertions get coarse; design coupling grows
Typical codebase
Many small classes with well-defined collaboration roles
Fewer larger classes with rich state
A practical heuristic: London-school suits services with rich collaboration (microservices, hexagonal architectures); Detroit-school suits state-rich domains (calculators, domain logic, parsers). Hybrid is the working norm.
When TDD Fits
Use TDD when the next behavior can be named before the implementation exists and feedback can arrive quickly enough to shape the code. Do not force it onto exploration where the target behavior is still unknown; spike first, then restart with tests once the behavior is nameable.
Situation
TDD fit
Reason
New behavior with a clear externally observable contract
Strong
The failing test can state the desired behavior before implementation details exist
Bug fix with a reproducible example
Strong
The regression test becomes the red step, then green proves the bug is fixed
Refactor with behavior already pinned
Supporting
Use TDD for new seams discovered during the refactor, but the refactor skill owns behavior preservation
Legacy code with no test harness
Characterize first
Golden-master or characterization tests may be needed before true TDD can begin safely
Research spike, unfamiliar API, or unclear product behavior
Weak until clarified
Exploration is legitimate; TDD starts once the desired behavior can be expressed
Visual polish or copy-only work
Usually weak
The feedback signal is often review, screenshot comparison, or usability judgment rather than binary test failure
Failure Modes and Corrections
Failure mode
Symptom
Correction
Test-first without refactor
Red-green-next-red cycles pile up, design does not improve
Stop after green; refactor production and test code while the suite stays green
Implementation-mirroring tests
Every internal rename or extraction breaks tests
Rewrite tests around observable behavior and natural boundaries
Accidental school choice
Some tests mock every collaborator while others assert broad state with no rationale
Name the school per module and align doubles with the chosen design pressure
Coverage Goodharting
Tests are added to satisfy a number but do not describe meaningful behavior
Use coverage as a smoke alarm, not the target; require a behavior or regression reason
Slow cycles
A single red-green-refactor loop takes hours
Shrink the behavioral increment or decompose the production unit before continuing
TDD used instead of testing strategy
The team writes tests first but still chooses the wrong level of test
Load testing-strategy first to choose unit/integration/contract/e2e surface, then apply TDD rhythm inside that surface
The Empirical Record
Multiple controlled studies and one large industrial study converge on a consistent directional finding: TDD codebases often show lower defect density at the cost of longer initial development time. Treat these numbers as evidence boundaries, not guarantees. The results depend on team discipline, cycle size, refactor quality, domain fit, and whether the team actually uses tests as design pressure rather than only as test-first paperwork.
Study
Finding
Nagappan et al. (2008) at Microsoft and IBM
TDD teams had 40-90% lower defect density; 15-35% longer initial development time
Erdogmus et al. (2005) controlled experiment
TDD subjects had higher external code quality; productivity comparable
Janzen & Saiedian (2008) meta-analysis
Code complexity reduced; cohesion improved; coupling reduced under TDD
Bissi et al. (2016) systematic review
27 of 39 studies showed TDD improved internal quality; 18 of 23 showed external quality improvement
The trade is well-documented. Teams abandoning TDD often do so on the visible-cost side (the time spent writing tests) without measuring the invisible-saving side (defects not encountered, rework not required).
Evaluation State
This public skill is reference-grounded and carries v6 understanding fields (mental_model, purpose, boundary, analogy, misconception), but its dedicated comprehension eval artifact is still planned. Keep eval_artifacts: planned, eval_state: unverified, and routing_eval: absent until a realistic eval suite exists, includes boundary/negative cases, runs in the same change, and produces evidence.
Verification
After applying this skill, verify:
Every increment of production code is preceded by a failing test that describes the behavior, not the implementation. If code was written before the test, the test is regression coverage, not TDD-born specification.
Each cycle includes a refactor beat. Cycles that go red → green → next-red are test-first development, not TDD.
The school being practiced (London / Detroit / hybrid) is intentional, not accidental. The test suite's character (mock-rich vs state-rich) reveals which school is in use.
When a test is hard to write, the design is examined. Hard-to-test code is the design-pressure signal; ignoring it (with test-only hooks, exposed internals, or stretched test boundaries) defeats the discipline.
Test names describe behaviors at the unit's natural boundaries — "calculates total with discount applied," not "tests calculateTotal() line 17."
Coverage is treated as a side effect, not a target. The discipline is the goal; coverage emerges from doing it.
The cycle's granularity stays small. Cycles that run hours indicate either over-large tests or under-decomposed production code.
For research/spike work where the target is unclear, exploration is allowed before TDD applies. The discipline is not universally appropriate.
Do NOT Use When
Instead of this skill
Use
Why
Choosing what to test, at which level, with what evidence
testing-strategy
testing-strategy owns the strategic-level decision; this skill owns the tactical design discipline
Constructing a mock, stub, fake, or spy
test-doubles-design
test-doubles-design owns the constructs; this skill owns the discipline that places them
Iterating on LLM behavior using an eval suite
eval-driven-development
eval-driven-development is the LLM analog with statistical (not binary) judgment
Performing a behavior-preserving structural change
refactor
refactor owns the technique; this skill calls it as the third beat
Process workflow guidance for a TDD session
the obra/superpowers test-driven-development skill on skills.sh
that skill is the workflow-shape complement; this one is concept-shape
Key Sources
Beck, K. (2002). Test-Driven Development: By Example. Addison-Wesley. The canonical book on Detroit-school TDD; defines red-green-refactor and the discipline's core form.
Freeman, S., & Pryce, N. (2009). Growing Object-Oriented Software, Guided by Tests (GOOS). Addison-Wesley. The canonical book on London-school TDD; defines outside-in mock-driven development.
Fowler, M. (2007). "Mocks Aren't Stubs". Practitioner-focused explanation of the London/Detroit school distinction and its consequences.
North, D. (2006). "Introducing BDD". The origin essay for Behavior-Driven Development as a vocabulary and tooling layer above TDD.
Skill Graph context
Classification
Subject: quality-assurance
Public: true
Domain: quality/testing
Scope: Use when reasoning about Test-Driven Development as a design discipline rather than a workflow: the red-green-refactor cycle as a feedback loop, the difference between London-school (outside-in, interaction-heavy, mock-driven) and Detroit-school (inside-out, state-heavy, classicist) TDD, the role of TDD as a design tool (how tests pressure code into more decomposable shapes), the connection between TDD and emergent design, the boundary between TDD and prior-test-suites, why TDD's failure mode is not 'no tests' but 'tests that mirror implementation', and the empirical record of TDD's effects on defect density, design quality, and development velocity. Do NOT use for the strategy of what to test at which level (use testing-strategy), the construction of test doubles (use test-doubles-design), the discipline of LLM eval iteration (use eval-driven-development), or general-software process workflow (use the obra/superpowers test-driven-development workflow skill — this skill is the concept-shape complement).
When to use
explain why writing the test first changes the design of the code under test
decide between London-school (mocks-as-design) and Detroit-school (state-verification) TDD for a new module
diagnose why the test suite is fragile under refactor — likely over-mocked interaction tests
explain why high test coverage with TDD is a side effect, not the goal
Triggers: should we write tests first, are mocks ruining the design, is TDD worth it, London school vs Detroit school, the tests changed every refactor
Not for
construct a mock, stub, or spy (use test-doubles-design)
decide what test levels (unit/integration/e2e) to invest in (use testing-strategy)
iterate on LLM behavior using an eval suite (use eval-driven-development)
Analogy: TDD is to code design what a piano teacher's metronome is to a student's playing — the rhythm is not the music, but it surfaces every uneven phrase, every rushed measure, every hesitation, in time to correct it before it ossifies into habit.
Common misconception: |
Grounding
Mode: universal
Truth sources: https://martinfowler.com/bliki/TestDrivenDevelopment.html, https://martinfowler.com/articles/mocksArentStubs.html, https://link.springer.com/article/10.1007/s10664-008-9062-z, https://ieeexplore.ieee.org/document/1423994, https://ieeexplore.ieee.org/document/4493089, https://doi.org/10.1016/j.infsof.2016.02.004, https://dannorth.net/introducing-bdd/
Keywords
test-driven development, TDD, red green refactor, London school, Detroit school, Chicago school, outside-in TDD, inside-out TDD, mockist, classicist
1---2name: test-driven-development3description: Use when reasoning about Test-Driven Development as a design discipline rather than a workflow: the red-green-refactor cycle as a feedback loop, the difference between London-school (outside-in, interaction-heavy, mock-driven) and Detroit-school (inside-out, state-heavy, classicist) TDD, the role of TDD as a design tool (how tests pressure code into more decomposable shapes), the connection between TDD and emergent design, the boundary between TDD and prior-test-suites, why TDD's failure mode is not 'no tests' but 'tests that mirror implementation', and the empirical record of TDD's effects on defect density, design quality, and development velocity. Do NOT use for the strategy of what to test at which level (use testing-strategy), the construction of test doubles (use test-doubles-design), the discipline of LLM eval iteration (use eval-driven-development), or general-software process workflow (use the obra/superpowers test-driven-development workflow skill — this skill is the concept-shape complement).4license: MIT5---6# Test-Driven Development78## Concept of the skill910TDD is design discipline through the test-writing lens. The unit of work is the red-green-refactor cycle: write one failing test for one increment of behavior (red), write the smallest production change that makes it pass (green), restructure the shape of both code and test while keeping all tests passing (refactor). Each cycle fits in a few minutes; long cycles indicate either insufficient test granularity or production complexity that should be decomposed. The test suite is the *design pressure* that shapes production code — writing tests first surfaces hard-to-test code at the moment when the underlying design discomfort (hard-to-use, hard-to-compose, hard-to-maintain) is still cheap to correct.1112Replaces test-after-implementation with test-driven design pressure. Solves the problem that tests written after the code mirror the implementation rather than the desired behavior — they lock the current shape in place, fragment under refactor, and miss the design feedback that comes only from articulating what a unit should do *before* writing it. Industrial evidence (Nagappan et al. 2008 at Microsoft and IBM across four teams) shows TDD codebases have 40-90% lower defect density at 15-35% longer initial development time; Erdogmus et al. (2005), Janzen & Saiedian (2008), and Bissi et al. (2016) converge on the same direction. Replaces "tests as regression coverage" with "tests as design pressure that produces regression coverage as a side effect."1314Distinct from testing-strategy, which owns the strategic question of what to test, at which level, with what evidence — strategy decides the surface, TDD prescribes the rhythm within it. Distinct from test-doubles-design, which owns mocks/stubs/fakes/spies as constructs — TDD's schools differ on how much test-doubles design matters to the practice (London heavily, Detroit lightly); the two compose. Distinct from eval-driven-development, the LLM analog where the unit of judgment is pass-rate over a sample rather than binary per-test pass/fail — both share the iteration-first-then-implement spirit but the math underneath differs. Distinct from refactor, which owns behavior-preserving structural change as a technique — TDD calls refactor as the third beat of red-green-refactor; refactor owns how to do it without breaking behavior. Distinct from the obra/superpowers TDD workflow skill on skills.sh, which is workflow-shape (process steps); this skill is concept-shape (the discipline's underlying mechanism). TDD is to code design what a piano teacher's metronome is to a student's playing — the rhythm is not the music, but it surfaces every uneven phrase, every rushed measure, every hesitation, in time to correct it before it ossifies into habit. The wrong mental model is that TDD is "writing tests first" as a procedural rule, where the tests are the point and the production code merely satisfies them. They are not the point. Tests are an *artifact* of doing design with a test-shaped tool; a team that "does TDD" by writing tests first without heeding the design pressure has the artifact without the practice, and will conclude TDD doesn't work because they will see only the cost (slower initial development) without the benefit (better-shaped code with lower defect density). Two adjacent misconceptions: that high coverage is the goal (coverage is a side effect; engineering tests to satisfy a coverage number Goodharts the discipline), and that the school doesn't matter (a practitioner who has not chosen London or Detroit has chosen by accident — the test suite's character, mock-rich vs state-rich, interaction-heavy vs state-heavy, reveals which school is in use whether the team named it or not).1516## Coverage1718The design discipline of writing the test before the production code that satisfies it, using the test-writing pressure to shape the code's design, and applying the red-green-refactor cycle as the unit of work. Covers the cycle structure (red → green → refactor), the design-pressure mechanism that makes TDD a design discipline rather than just a test-first habit, the London/Detroit/Chicago school distinctions (mockist vs classicist, outside-in vs inside-out, interaction vs state), the relationship between TDD and emergent design, the empirical record (Nagappan 2008 at Microsoft/IBM and meta-analyses since), the boundary between TDD and BDD, and the failure modes (skipping refactor, ignoring design pressure, mock-heavy fragile tests, coverage-as-goal Goodharting).1920## Philosophy of the skill21TDD is design through the test-writing lens. Every test you sit down to write is a moment of design: what is this unit, what does it own, what does it delegate, what does its interface look like from the outside. The discomfort of writing a hard-to-test piece of code is the same discomfort that will eventually arrive as hard-to-use, hard-to-maintain, hard-to-compose code; TDD makes that discomfort visible at the moment when correcting it is cheap.2223The tests are not the point. The tests are an artifact of doing design with a test-shaped tool. A team that "does TDD" by writing tests first without heeding the design pressure has the artifact without the practice; they will conclude TDD doesn't work because they will see only the cost (slower initial development) without the benefit (better-shaped code with lower defect density).2425The schools matter. London and Detroit produce different code under the same red-green-refactor cycle, because they apply the design pressure to different surfaces. A practitioner who has not chosen a school has chosen by accident, and the test suite's character — interaction-heavy or state-heavy, mock-rich or mock-sparse, outside-in or inside-out — reveals which they chose without knowing.2627## The Cycle In Detail2829| Beat | Activity | Stop condition | Common mistake |30|---|---|---|---|31| Red | Write one failing test for one increment of desired behavior | The test compiles and fails for the right reason (not a syntax error) | Writing a passing test (no design pressure); writing many tests at once (loses the increment) |32| Green | Write the smallest production change that makes the test pass | The test passes; no other tests broke | Writing more than needed; "fake it till you make it" abandoned too early |33| Refactor | Improve the shape of both code and test while keeping all tests passing | The structure is cleaner; tests still pass | Skipping this beat; refactoring into bigger changes that break tests |3435Each cycle should fit in a few minutes — long cycles indicate either insufficient test granularity or production complexity that should be decomposed before continuing.3637## London School vs Detroit School — A Practical Comparison3839| Property | London (mockist, outside-in) | Detroit (classicist, inside-out) |40|---|---|---|41| Origin | Freeman & Pryce, *GOOS* (2009) | Beck, *TDD by Example* (2002) |42| Starting point | Acceptance test or service boundary | A single concrete unit |43| Test focus | Interactions (who called whom with what) | Observable state changes |44| Test doubles | Central — every new collaborator becomes a mock | Sparse — used only when needed (DB, external service) |45| Design pressure | On collaborator interfaces (the mocks shape them) | On units' responsibilities and state shape |46| Failure mode | Tests mirror implementation; refactor breaks them | State assertions get coarse; design coupling grows |47| Typical codebase | Many small classes with well-defined collaboration roles | Fewer larger classes with rich state |4849A practical heuristic: London-school suits services with rich collaboration (microservices, hexagonal architectures); Detroit-school suits state-rich domains (calculators, domain logic, parsers). Hybrid is the working norm.5051## When TDD Fits5253Use TDD when the next behavior can be named before the implementation exists and feedback can arrive quickly enough to shape the code. Do not force it onto exploration where the target behavior is still unknown; spike first, then restart with tests once the behavior is nameable.5455| Situation | TDD fit | Reason |56|---|---|---|57| New behavior with a clear externally observable contract | Strong | The failing test can state the desired behavior before implementation details exist |58| Bug fix with a reproducible example | Strong | The regression test becomes the red step, then green proves the bug is fixed |59| Refactor with behavior already pinned | Supporting | Use TDD for new seams discovered during the refactor, but the refactor skill owns behavior preservation |60| Legacy code with no test harness | Characterize first | Golden-master or characterization tests may be needed before true TDD can begin safely |61| Research spike, unfamiliar API, or unclear product behavior | Weak until clarified | Exploration is legitimate; TDD starts once the desired behavior can be expressed |62| Visual polish or copy-only work | Usually weak | The feedback signal is often review, screenshot comparison, or usability judgment rather than binary test failure |6364## Failure Modes and Corrections6566| Failure mode | Symptom | Correction |67|---|---|---|68| Test-first without refactor | Red-green-next-red cycles pile up, design does not improve | Stop after green; refactor production and test code while the suite stays green |69| Implementation-mirroring tests | Every internal rename or extraction breaks tests | Rewrite tests around observable behavior and natural boundaries |70| Accidental school choice | Some tests mock every collaborator while others assert broad state with no rationale | Name the school per module and align doubles with the chosen design pressure |71| Coverage Goodharting | Tests are added to satisfy a number but do not describe meaningful behavior | Use coverage as a smoke alarm, not the target; require a behavior or regression reason |72| Slow cycles | A single red-green-refactor loop takes hours | Shrink the behavioral increment or decompose the production unit before continuing |73| TDD used instead of testing strategy | The team writes tests first but still chooses the wrong level of test | Load `testing-strategy` first to choose unit/integration/contract/e2e surface, then apply TDD rhythm inside that surface |7475## The Empirical Record7677Multiple controlled studies and one large industrial study converge on a consistent directional finding: TDD codebases often show lower defect density at the cost of longer initial development time. Treat these numbers as evidence boundaries, not guarantees. The results depend on team discipline, cycle size, refactor quality, domain fit, and whether the team actually uses tests as design pressure rather than only as test-first paperwork.7879| Study | Finding |80|---|---|81| Nagappan et al. (2008) at Microsoft and IBM | TDD teams had 40-90% lower defect density; 15-35% longer initial development time |82| Erdogmus et al. (2005) controlled experiment | TDD subjects had higher external code quality; productivity comparable |83| Janzen & Saiedian (2008) meta-analysis | Code complexity reduced; cohesion improved; coupling reduced under TDD |84| Bissi et al. (2016) systematic review | 27 of 39 studies showed TDD improved internal quality; 18 of 23 showed external quality improvement |8586The trade is well-documented. Teams abandoning TDD often do so on the visible-cost side (the time spent writing tests) without measuring the invisible-saving side (defects not encountered, rework not required).8788## Evaluation State8990This public skill is reference-grounded and carries v6 understanding fields (`mental_model`, `purpose`, `boundary`, `analogy`, `misconception`), but its dedicated comprehension eval artifact is still planned. Keep `eval_artifacts: planned`, `eval_state: unverified`, and `routing_eval: absent` until a realistic eval suite exists, includes boundary/negative cases, runs in the same change, and produces evidence.9192## Verification9394After applying this skill, verify:95- [ ] Every increment of production code is preceded by a failing test that describes the behavior, not the implementation. If code was written before the test, the test is regression coverage, not TDD-born specification.96- [ ] Each cycle includes a refactor beat. Cycles that go red → green → next-red are test-first development, not TDD.97- [ ] The school being practiced (London / Detroit / hybrid) is intentional, not accidental. The test suite's character (mock-rich vs state-rich) reveals which school is in use.98- [ ] When a test is hard to write, the design is examined. Hard-to-test code is the design-pressure signal; ignoring it (with test-only hooks, exposed internals, or stretched test boundaries) defeats the discipline.99- [ ] Test names describe behaviors at the unit's natural boundaries — "calculates total with discount applied," not "tests `calculateTotal()` line 17."100- [ ] Coverage is treated as a side effect, not a target. The discipline is the goal; coverage emerges from doing it.101- [ ] The cycle's granularity stays small. Cycles that run hours indicate either over-large tests or under-decomposed production code.102- [ ] For research/spike work where the target is unclear, exploration is allowed before TDD applies. The discipline is not universally appropriate.103104## Do NOT Use When105106| Instead of this skill | Use | Why |107|---|---|---|108| Choosing what to test, at which level, with what evidence | `testing-strategy` | testing-strategy owns the strategic-level decision; this skill owns the tactical design discipline |109| Constructing a mock, stub, fake, or spy | `test-doubles-design` | test-doubles-design owns the constructs; this skill owns the discipline that places them |110| Iterating on LLM behavior using an eval suite | `eval-driven-development` | eval-driven-development is the LLM analog with statistical (not binary) judgment |111| Performing a behavior-preserving structural change | `refactor` | refactor owns the technique; this skill calls it as the third beat |112| Process workflow guidance for a TDD session | the obra/superpowers `test-driven-development` skill on skills.sh | that skill is the workflow-shape complement; this one is concept-shape |113114## Key Sources115116- Beck, K. (2002). *Test-Driven Development: By Example*. Addison-Wesley. The canonical book on Detroit-school TDD; defines red-green-refactor and the discipline's core form.117- Freeman, S., & Pryce, N. (2009). *Growing Object-Oriented Software, Guided by Tests* (GOOS). Addison-Wesley. The canonical book on London-school TDD; defines outside-in mock-driven development.118- Nagappan, N., Maximilien, E. M., Bhat, T., & Williams, L. (2008). ["Realizing quality improvement through test driven development: results and experiences of four industrial teams"](https://link.springer.com/article/10.1007/s10664-008-9062-z). *Empirical Software Engineering*, 13(3), 289-302. The Microsoft/IBM industrial study showing 40-90% defect-density reduction.119- Erdogmus, H., Morisio, M., & Torchiano, M. (2005). ["On the effectiveness of the test-first approach to programming"](https://ieeexplore.ieee.org/document/1423994). *IEEE Transactions on Software Engineering*, 31(3), 226-237. Controlled experiment on TDD's productivity and quality effects.120- Janzen, D., & Saiedian, H. (2008). ["Does Test-Driven Development Really Improve Software Design Quality?"](https://ieeexplore.ieee.org/document/4493089). *IEEE Software*, 25(2). Meta-analysis on TDD's effect on code complexity, cohesion, and coupling.121- Bissi, W., Serra Seca Neto, A. G., & Emer, M. C. F. P. (2016). ["The effects of test driven development on internal quality, external quality and productivity: A systematic review"](https://doi.org/10.1016/j.infsof.2016.02.004). *Information and Software Technology*, 74, 45-54. Systematic review of controlled TDD studies.122- Fowler, M. (2007). ["Mocks Aren't Stubs"](https://martinfowler.com/articles/mocksArentStubs.html). Practitioner-focused explanation of the London/Detroit school distinction and its consequences.123- North, D. (2006). ["Introducing BDD"](https://dannorth.net/introducing-bdd/). The origin essay for Behavior-Driven Development as a vocabulary and tooling layer above TDD.124125## Skill Graph context126127<!-- skill-graph-context:start (generated — do not edit by hand) -->128129**Classification**130- Subject: `quality-assurance`131- Public: `true`132- Domain: `quality/testing`133- Scope: Use when reasoning about Test-Driven Development as a design discipline rather than a workflow: the red-green-refactor cycle as a feedback loop, the difference between London-school (outside-in, interaction-heavy, mock-driven) and Detroit-school (inside-out, state-heavy, classicist) TDD, the role of TDD as a design tool (how tests pressure code into more decomposable shapes), the connection between TDD and emergent design, the boundary between TDD and prior-test-suites, why TDD's failure mode is not 'no tests' but 'tests that mirror implementation', and the empirical record of TDD's effects on defect density, design quality, and development velocity. Do NOT use for the strategy of what to test at which level (use testing-strategy), the construction of test doubles (use test-doubles-design), the discipline of LLM eval iteration (use eval-driven-development), or general-software process workflow (use the obra/superpowers test-driven-development workflow skill — this skill is the concept-shape complement).134135**When to use**136- explain why writing the test first changes the design of the code under test137- decide between London-school (mocks-as-design) and Detroit-school (state-verification) TDD for a new module138- diagnose why the test suite is fragile under refactor — likely over-mocked interaction tests139- explain why high test coverage with TDD is a side effect, not the goal140- Triggers: `should we write tests first`, `are mocks ruining the design`, `is TDD worth it`, `London school vs Detroit school`, `the tests changed every refactor`141142**Not for**143- construct a mock, stub, or spy (use test-doubles-design)144- decide what test levels (unit/integration/e2e) to invest in (use testing-strategy)145- iterate on LLM behavior using an eval suite (use eval-driven-development)146147**Related skills**148- Verify with: `refactor`, `testing-strategy`149- Related: `eval-driven-development`, `type-safety`, `testing-strategy`, `test-doubles-design`, `refactor`150151**Concept**152- Mental model: |153- Purpose: |154- Boundary: |155- Analogy: TDD is to code design what a piano teacher's metronome is to a student's playing — the rhythm is not the music, but it surfaces every uneven phrase, every rushed measure, every hesitation, in time to correct it before it ossifies into habit.156- Common misconception: |157158**Grounding**159- Mode: `universal`160- Truth sources: `https://martinfowler.com/bliki/TestDrivenDevelopment.html`, `https://martinfowler.com/articles/mocksArentStubs.html`, `https://link.springer.com/article/10.1007/s10664-008-9062-z`, `https://ieeexplore.ieee.org/document/1423994`, `https://ieeexplore.ieee.org/document/4493089`, `https://doi.org/10.1016/j.infsof.2016.02.004`, `https://dannorth.net/introducing-bdd/`161162**Keywords**163- `test-driven development`, `TDD`, `red green refactor`, `London school`, `Detroit school`, `Chicago school`, `outside-in TDD`, `inside-out TDD`, `mockist`, `classicist`164165<!-- skill-graph-context:end -->
Run npx skillmds@latest add jacob-balslev/test-driven-development in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Use when reasoning about Test-Driven Development as a design discipline rather than a workflow: the red-green-refactor cycle as a feedback loop, the difference between London-school (outside-in, interaction-heavy, mock-driven) and Detroit-school (inside-out, state-heavy, classicist) TDD, the role of TDD as a design tool (how tests pressure code into more decomposable shapes), the connection between TDD and emergent design, the boundary between TDD and prior-test-suites, why TDD's failure mode is not 'no tests' but 'tests that mirror implementation', and the empirical record of TDD's effects on defect density, design quality, and development velocity. Do NOT use for the strategy of what to test at which level (use testing-strategy), the construction of test doubles (use test-doubles-design), the discipline of LLM eval iteration (use eval-driven-development), or general-software process workflow (use the obra/superpowers test-driven-development workflow skill — this skill is the concept-shape complement). It is listed under AI & ML on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Capability flags: makes network calls. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free. This skill is licensed under MIT.
jacob-balslev (@jacob-balslev) published this skill. Their other Agent Skills are listed on their SkillMD profile.