A coding agent will write a few hundred lines in the time it takes me to read the first fifty. Typing was never the bottleneck in software, and now writing isn’t either. The hard part is knowing whether the code is right.

The teams I’ve seen get real value from agents aren’t the ones with the cleverest prompts. They’re the ones that already had a test suite they trusted. That suite is the harness: it limits what the agent can break, and it tells both of you, quickly and without argument, when something went wrong.

Self-testing code has a second user

Martin Fowler describes self-testing code as a suite you can run with one command and trust to catch bugs. The payoff was always the feedback loop: make a change, run the tests, know. At Thoughtworks we treated test-driven development and continuous integration as sensible defaults for exactly that reason.

An agent lives entirely inside that loop. It doesn’t know why the code is shaped the way it is, or which corner broke production last spring, and it’s confident regardless. The test suite is the only part of the team’s knowledge it can actually run.

So the qualities that always made tests good matter more now, and the weaknesses we used to tolerate cost more.

What makes a good harness

Fast. An agent runs your suite dozens of times on a single task. If that takes twenty minutes, it either skips it or you pay in wall-clock time and tokens. Push most checks down to the narrowest level that can catch the bug, the old test pyramid argument, and keep a few broad tests to prove the wiring.

Deterministic. A flaky test teaches the agent that red means nothing. So it retries, adds a sleep, or loosens the assertion until it goes green. People do the same; an agent just does it faster and without guilt. Fix flaky tests or quarantine them, but never leave them in the loop.

Pinned to the desired behaviour, not implementation. This one matters most. Tests coupled to internals break on every legitimate refactoring, so the agent learns that editing tests is part of the job. Once that’s normal, the harness bends to whatever the agent wrote. Tests that go through the public interface and assert on what the software does let the agent restructure freely while holding the line on behaviour.

Clear when they fail. A failure message is now a prompt. expected 3, got 4 sends the agent guessing. expected a returning customer's total to be 90.00 after discount, got 100.00 points it at the problem.

Who writes the tests?

AI can write good tests, with the right guidance and judgement behind it. Tests are the specification, so I delegate the typing, not the thinking. Of course, LLMs are very good thinking partners too: they’re great for inspiration, for getting unstuck, or for giving a half-formed idea some shape. The call on what the software should do still stays with me.

Left unguided, an agent that writes the code and its tests together tends to describe what the code does rather than what it should do. The tests pass, look thorough, and pin down the bugs as carefully as the features.

That’s why testing fundamentals matter more than ever. The FIRST principles (fast, independent, repeatable, self-validating, timely), testing behaviour rather than implementation, one clear reason for each test to fail: these used to be good habits. Now they’re the guidance the agent works from.

The tests I review most carefully are the first ones on a project. An agent follows the conventions it finds, so those first tests set the pattern for the next hundred. If the convention is great, the chances are high the agent produces good tests on its own, and the software gets built faster and better at the same time.

After that I still read test changes more carefully than production code. A diff that touches both a test and the code under it deserves a slower read, and mutation testing is a cheap way to find assertions that never fail.

All of this depends on recognising a good test when you see one, and that’s where I see a challenge. Most of us built that eye the slow way: writing poor tests, living with them, and learning what hurt. If agents write most of the tests from day one, I’m not sure how new programmers will develop it. My best guess is that it has to be taught on purpose, through pairing and code review, because it no longer comes for free.

The same investment, paid twice

None of this is new. Fast, deterministic, behaviour-focused tests are what we were already arguing for, because they let people change code without fear. The difference is how quickly their absence hurts. It used to show up slowly, as refactorings nobody dared to start and nervous releases. With an agent it shows up in an afternoon.

A good testing strategy was always a harness for the team. Now it’s also the harness for the fastest and least cautious contributor you’ve ever had.

So pay attention to how your tests are written, and to the strategy behind them: which tests run on every commit, which ones gate a deployment, and how quickly your CI and CD pipeline tells you something broke. Coming up with a good strategy still takes understanding your software’s context: what it does, who relies on it and what a failure costs. That part is still our job.