TDD Doesn't Work for LLMs


Introduction#

TDD is one of the most valuable disciplines a developer can practice. It forces clarity of intent before implementation. It catches design problems early. It creates a safety net. For developers, it works.

But a growing number of teams are prescribing TDD as a practice for AI-assisted development. Write a failing test, have the LLM make it pass, repeat. The reasoning sounds logical: if TDD improves human code, it should improve AI-generated code too.

That reasoning misidentifies what TDD actually optimizes for. The Three Laws are not a quality mechanism. They are a cost mechanism. They constrain step size so that being wrong stays cheap. When the cost of correction changes, the optimal step size changes with it.

This is specifically about Uncle Bob’s Three Laws of TDD as a literal practice applied to LLMs. It is not an argument against testing, and it is not a critique of iterative development.

The Three Laws#

Robert C. Martin defined TDD through three laws:

  1. You may not write production code until you have written a failing unit test.
  2. You may not write more of a unit test than is sufficient to fail, and not compiling counts as failing.
  3. You may not write more production code than is sufficient to pass the currently failing test.

These three rules create a tight loop. Write one small assertion. Write just enough code to satisfy it. Repeat. You never get more than a few lines ahead of a passing test. Every step is small, provable, and reversible.

The discipline is the constraint. Never get ahead of yourself. Never write more than the next small provable step. The laws keep you in lockstep between intent and implementation.

What the Three Laws Actually Solve#

Each law addresses a specific human tendency.

Law 1 solves for premature implementation. Developers start coding before they know what “done” looks like. Writing the failing test first forces you to articulate your intent before you get lost in implementation details.

Law 2 solves for scope creep in tests. Developers write sprawling tests that try to prove too much at once. Constraining each test to the smallest sufficient failure keeps the scope narrow and the feedback clear.

Law 3 solves for over-building. Developers write code for the next three requirements, not just the current one. Capping production code at exactly what the failing test demands prevents premature abstraction and gold-plating.

Together, the Three Laws form a paradigm: a helpful constraint that keeps developers focused and organized. They impose a rhythm that prevents the most common ways developers go off course.

For developers, that rhythm works. The question is whether the rhythm transfers to agents.

The Cost of Being Wrong Changes the Size of the Step#

The Three Laws exist to minimize the cost of being wrong. Each law constrains the size of the next step so that when you go off course, you have only wasted a small amount of effort.

For a developer, that constraint is essential. Writing code takes time. Debugging takes time. Rewriting a module you spent two hours on is painful. Small steps keep the price of a wrong turn low.

LLMs suffer from every problem the Three Laws address. They write code without knowing what done looks like. They write tests that sprawl beyond what is needed. They over-build. The Three Laws would genuinely help with those failure modes.

But the laws solve for cost, not correctness. The reason developers take small steps is that large steps are expensive to undo. An LLM can regenerate a module in a fraction of the time a developer would take. The cost of a wrong turn is lower. Not because the LLM makes fewer mistakes, but because correction is faster.

When the cost of correction drops, you can take bigger steps and still maintain a similar economic safety margin to what tiny TDD cycles give a developer. The same principle that makes TDD’s small steps valuable for developers, minimizing waste when you are wrong, is what makes those same small steps unnecessary overhead for an agent. The math changes when the rewrite gets cheaper.

This is not an argument that LLMs do not need course correction. They do. It is an argument that following Uncle Bob’s Three Laws verbatim, one assertion at a time, one line of production code at a time, optimizes for a constraint that does not apply: human speed.

In Practice, It Feels Wrong Because It Is Wrong#

Getting an LLM to follow the Three Laws verbatim is an exercise in friction. Write one line of production code. Stop. Write a test for it. Stop. Update the production code. Stop. Update the test. It consumes tokens, fragments the model’s coherence across many tiny turns, and produces worse results than letting it work in larger chunks.

The back-and-forth of tiny incremental turns fights against how LLMs actually generate good output. LLMs produce their best work with sufficient context and room to produce a coherent whole. Forcing one-assertion-at-a-time cycles breaks the output into fragments that lose the thread of the larger design.

The Three Laws optimize for a developer’s attention span and keystroke cost. A developer needs the small-step rhythm because the alternative, writing a full module and hoping it works, is risky when each line took real time to produce. An agent does not have an attention span to manage or keystrokes to economize. The constraint solves a problem it does not have.

Testing Is More Important Than Ever#

None of this is an argument against testing. It is the opposite.

AI-generated code needs more verification, not less. The failure modes of LLMs, hallucination, pattern mimicry, subtle incorrectness that compiles and passes a cursory review, make testing essential. Every module an LLM produces should be verified against clear acceptance criteria.

The argument is about the discipline of TDD versus the artifact of tests. The Three Laws prescribe a specific ordering, a specific incrementalism, a specific human-paced cycle. That ordering is the part that does not transfer. The tests themselves are the part that matters more than ever.

Separate the ceremony from the outcome. The outcome is verified, working code backed by tests. The ceremony is the specific step-by-step rhythm designed for a developer sitting at a keyboard. Keep the outcome. The ceremony is optional.

Conclusion#

TDD is a discipline, not a dogma. Its value comes from how it shapes a developer’s thinking: forcing intent before implementation, constraining scope, preventing over-building. Those are developer problems solved by a developer-speed paradigm.

Agents have the same problems. They just operate at a different speed. When correction gets cheaper, the step size that makes economic sense gets larger. The Three Laws were calibrated for a developer who types, thinks, debugs, and rewrites at human pace. That calibration does not transfer to agents.

Keep the tests. Drop the ceremony.