TDD is dead. DHH declared it so back in2014. If it ever had life, the constraints it placed on developers suffocated it and meant developers abandoned the practice for more pragmatic approaches to testing.
But what if it was just one of those ideas before its time? What if, with our newfound ability to get machines to crank out poor-quality code by the megabyte,TDD could be reborn as the essential quality control mechanism our AI-assisted future needs?
Kent Beck introducedTest-Driven Development back in the late 90s as part of Extreme Programming. The promise was compelling:writing tests before implementation code produced cleaner designs, fewer bugs, and a comprehensive safety net for future changes. By the early 2000s, TDD had become the darling of the Agile movement. Books were written, conferences held, and training programs developed, all extolling the virtues of the red-green-refactor cycle.
But as with many revolutionary ideas, the backlash was inevitable. The practice required significant discipline, slowed initial development, and sometimes forced artificial design decisions it was almost the antithesis of the move fast and break things momentum model that dominates startup culture. DHH's inflammatory 2014 blog post" TDD is Dead. Long Live Testing "killed the idea with the hipster coders at the time.
Teams moved to more flexible approaches like test-after development or focused primarily on integration and end-to-end tests rather than the unit-level focus of classic TDD. Others simply reduced their testing disciplines altogether, favoring velocity over verification. Many veteran teams quietly continue practicing TDD, or at least the spirit of it. Still, the rigid orthodoxy oftest-first development has become more of a niche practice than the industry standard.
But that was a time when code was good. What about when slop starts to takeover codebases?
There's trouble in paradise.
It's not your code that's bad, obviously. It's AI's fault. Cursor, Windsurf,Lovable they are pumping out slop in epic proportions. Nothing to do with you.
Quality issues in AI code are a given. GitHub's own research acknowledges a "downward pressure on code quality" when Copilot enters the picture. Developers are pushing more mistakes, introducing more redundancies, and building increasingly complex systems all the while feeling more productive.
The problems are legion:
Automation bias the tendency to trust computer-generated answers uncritically leads devs to accept AI suggestions without adequate scrutiny. Tab. Tab. Tab. Tab. The end result? We're creating more code than ever at a pace that would have seemed magical just a few years ago but much of it is crud. We've lost the natural friction that once forced reflection and careful design.
This is precisely where TDD comes back into the picture.
If AI pumps out plausible-but-poor code, we need a reliable definition of "right." That's TDD in a nutshell.
TDD creates an unambiguous target for AI to hit by defining expected behavior in executable form before implementation. Write a test, watch it fail, then unleash the AI to make it pass. The test provides guardrails the AI can't wander off into useless territory because the test specifies exactly what's required. It either passes or fails. No debate.
This approach neutralizes AI's worst tendencies:
This is what Kent Beck meant when he observed that as AI automates routine coding, testing skills become exponentially more valuable:
When machines can write code faster than humans, our value shifts to defining problems correctly and verifying solutions work as intended.
The irony is perfect. Once rejected for slowing developers down, TDD becomes the tool that lets us safely accelerate with AI. TDD transforms from burden to essential control mechanism. It's no longer about slowing down to write tests it's about writing tests so AI can safely speed up.
So, how do we do this in practice? How does TDD work when AI is generating both tests and code? Here's a possible workflow that leverages the strengths of both:
This workflow flips the traditional AI coding experience on its head. Instead of "generate some code and hope it's right," you define correctness first, then generate code to match. Humans stay firmly in control of what gets built, whileAI handles the mechanical implementation details.
The beauty is in the balance: humans doing what they do best (defining problems, spotting edge cases, maintaining architectural vision) and AI doing what it excels at (generating implementation code quickly).
We're likely heading toward a world where developers spend more time defining problems through tests than writing implementation code. The human's role shifts toward being the quality architect who specifies, verifies, and refines rather than the code typist. Think of it as a new division of labor: humans handling the "what" and "why," while AI tackles the "how."
AI tools themselves will evolve to support this paradigm. Imagine IDEs that automatically generate test suites from requirements documents, or AI assistants that flag when your implementation exceeds your tests' specifications the ultimate YAGNI enforcer. The concept of "test coverage" may transform into"requirement coverage," measuring how completely your tests capture the intended behavior.
For technical leaders, this shift demands investment in testing culture. Teams that build expertise in writing good tests will thrive with AI, while those chasing raw output without quality guardrails will drown in technical debt. The tools have changed dramatically since Kent Beck first proposed Test-DrivenDevelopment, but its core insight remains more relevant than ever: defining success clearly before you begin is the surest path to achieving it.