This page looks best with JavaScript enabled

AI and the future of TDD

 ·   ·  ☕ 4 min read

Tame your AI assistant’s nonsesne with TDD.

Let me start by spoiling the conclusion: AI code-generation will force an immediate future where TDD becomes a strict requirement for software development, and code quality will only be relevant for tests.

The Issue

We can all agree that AI generated code kinda sucks.
It’s often messy, buggy or just plain made up stuff crammed together.

You need to be super careful with it, double check every line it produces.
Troubleshooting bugs is a huge pain with generated code.

This is a shame because the efficiency is undeniable: I doubt that the average dev can produce code at a similar speed that your Copilot/GPT thing can.
Not to mention the fact that an AI can parse documentation orders of magnitude faster than we can.

Of course, speed is not the be-all and end-all, but we do get paid by the hour so…

How can we take advantage of the AI’s ability to generate code quickly while ensuring the code actually works, and does so as expected/required?
If only there was an (often overlooked) approach to software development that could guarantee the behavior of a piece of code…

The Idea

It’s quite simple: make AI a part of the TDD cycle.

I write a little test, the AI makes it pass.
I write another little test for the same SUT, the AI makes it pass as well, either adapting current code or generating new one.

This way, there’s at leas one thing we could always assert: the generated code makes the test/s pass.
Given enough quality tests, this would allow us to ensure the code’s behavior.

For some, this would be pretty much business as usual (except we would only write tests and treat production code as a black box).
For others, this would mean learning a completely new skill and way of thinking.

Depends on how you currently feel about TDD.

The Necessity

So that’s cool and all but I said “strict requirement”, why is that?

Well, take two equally capable developers: Peter and John.
Similar experience, similar skills.

Peter uses the previously described TDD+AI approach while John doesn’t.

While only worrying about tests, Peter will produce working software that is guaranteed to behave as expected (so far as the tests correctly describe its behavior).
Since he wouldn’t have to worry about production code, this would require much less time than the traditional TDD approach.

John faces a difficult decision: either use AI and embrace its weaknesses or avoid at the cost of more development time to produce comparable functionality.

Simply using AI might be faster than Peter’s approach but will certainly (at least with the current state of things) produce buggier and less maintainable code.
Besides, the amount of trial and error required to get the prompt just right might actually take longer that Peter’s approach.

Avoiding AI altogether will be significantly slower than Peter’s (whether John decides to be a good boy and also write tests or not).

Add a little “survival of the fittest” and voilà, Peter takes John’s job.

The Consequence

As you might imagine, the proposed approach would imply a near-total neglect of production code.
This is a big jump from our current notions of Clean Code or maintainability. They may, at the very least, become outdated.

Consider that, if you can produce code in seconds it doesn’t really matter if it’s easy to understand and modify in the future: just tell the AI to rewrite the thing if your requirements change.

Remember, you’ll have your test suite to ensure no current behavior is lost.
Just add more tests for the new behavior you need to implement (or the bugs you need to fix).

If the vision is accurate, we won’t be spending much time (if any) in the production code at all.
That will be the AI’s territory, while we will mostly work with the tests, using them to ensure the AI behaves correctly and doesn’t make stuff up.

This doesn’t mean that ideas about Clean Code or maintainability will be irrelevant.
Rather, they will find their place within the tests.

Those ideas where meant for us humans anyway, not for the machine.
If we migrate our efforts to the tests, they’ll come along for the ride.

TDD advocates have always claimed we should treat test code as a first class citizen, with the same care that we put into our production code.
Well, they can shout a big fat “told you so!” right about now.

Support the author with