Is test-driven development still relevant?
September 2, 2026
It's been exactly a year since I went all-in with AI-assisted coding. In August 2025, I had to build a Salesforce plugin, and I decided to give it a try with Claude Code. I've been a huge advocate for test-driven development for years, but lately I'm not as vocal about it as I used to be. Does that mean that test-driven development isn't relevant anymore?
Why test-driven development?
Whenever we're building something, be it software or hardware, we need to operate within certain constraints. These can be deadlines, budget, compliance requirements, team knowledge, hardware capabilities, security, reliability or something else. Then there are also constraints teams set for themselves to streamline their development process. For example: auto code formatting, linting, or release process.
Automatic verification of expectations
The main goal is always to bring as much value to users as possible. And to do that, the software must meet the expectations. The easiest way to ensure that software meets expectations is through automated tests. You can think of test-driven development as a constraint that pushes you towards having such tests. By the very nature of it, you need to make your code testable. You simply can't practice it if you can't write the tests.
More modular code
It's very hard to test code where the coupling is very high. For example, you'll need to use a lot of mocking, patching, and other trickery to test a function that directly interacts with Redis, PostgreSQL, Stripe API, HubSpot API, Kafka, and S3. Your life will get much easier if you build components interacting with each of these dependencies and then use dependency injection for the function that orchestrates interactions with all of them. So, by practicing test-driven development and focusing on behavior, you push yourself towards more modular code with lower coupling.
Curious about how to focus on testing behavior instead of implementation details? Check this blog post!
Deeper understanding
If you want to write valuable tests, you need to assert expected behavior. Quite often things seem very clear until you try to verify them with a set of tests. Then you realize that many details are missing or that the whole logic has flaws, like mutually exclusive requirements. Realizing that very early in the process is much cheaper compared to spending hours of work on implementation just to realize that most fundamental things need to be changed.
Step by step
Another great consequence of practicing test-driven development is that it forces you to take things step by step. The red-green-refactor cycle requires you to focus on one thing at a time:
- Red - write a failing test for the next expectation
- Green - make the minimal change needed to make the test pass
- Refactor - clean up the code and improve the design
It forces the habit of asking yourself, "What's the next smallest change I can make to improve/do something?" And that's essential if you want to continuously deploy and release to production. You simply can't afford that with large changes, as it's too risky to miss something and cause an outage.
Become a better engineer, one article at a time.
Practices, mindsets, and habits that actually move the needle. Delivered weekly to your inbox.
Is test-driven development still relevant in the AI-era?
While it may seem that test-driven development is obsolete, I don't think that's really the case. I think its core ideas are still very much alive and relevant.
You can think of test-driven development as a form of scientific method. For example, your hypothesis can be "Our system supports importing a mailing list from an XLS file." Then you come up with a set of experiments, tests in this case, that verify this hypothesis: - Emails from an XLS file are stored in the database after import - Emails from all sheets in the XLS file are stored in the database after import - File with unsupported encoding is rejected with an error - File with unknown columns is rejected with an error - File with values that are not email addresses is rejected with an error
With AI, it doesn't make sense for you to go test by test yourself. You can let AI do its work, and then you just review the output. Start the review with the tests. You should ask yourself:
- Are these tests matching my expectations as per my set of experiments to verify my hypothesis?
- Are there any redundant tests?
- Are there any tests that are of no value?
- Are there any tests that verify the behavior that I don't expect?
Once you're happy with tests, you can move towards reviewing the code. In my experience, whenever I'm happy with tests, the code isn't too bad either. And that's not at all surprising. As mentioned above, pushing for testability naturally pushes you towards more modular code and requires a deep understanding of the problem that you're solving.
Test-driven development with AI
AI changed quite a few things around how we develop software in the last year.
Since AI is writing all of my code and all of my tests, the red-green-refactor cycle now looks like this:
- Red - Define the set of tests that you expect to see for the next step and prompt the agent to implement
- Green - Review the passing tests written by the agent and prompt for test improvements until happy
- Refactor - Review the implementation and prompt for refactoring until happy
My team's CLAUDE.md file contains Use red-green TDD while developing. as suggested by Simon Willison.
We've added it after experimenting with a couple of approaches, and this one consistently yielded the most valuable tests and the cleanest implementations from the initial prompts.
So the agent still goes test by test, but I don't watch over it to check that tests are actually written first while it's doing its job.
There's no need for micromanagement - it doesn't work with people, and it doesn't work with agents.
All I care about is the end result:
- Is all the expected behavior tested with valuable tests?
- Are there any assumptions made by the coding agent that shouldn't be there?
- Are there any weird test setups?
- Are there any useless tests?
- Is there some code that I don't understand?
- Is there some code that is hard to read?
- Are all style and security checks passing?
- Are all tests passing?
If I'm happy with all the answers, we're good to go. The goal is still the same - to bring as much value to users as possible.
Conclusion
The mechanics of test-driven development have changed - I no longer write tests by hand, one at a time, as that adds too much friction when working with AI agents. But its core ideas are more relevant than ever. There's still friction, of course - you need to review regularly and stay involved in the development process. For example, you can't let AI go ballistic for 48 hours. But that's actually the point. Frequent course-correction allows you to release to production continuously and deliver value to users as early as possible.
Happy engineering!