TDD and Agentic Programming

Note: I would recommend reading my blog post on the core concepts of TDD before proceeding with this post, so that we have a common understanding with regards to TDD.

I was giving a talk on TDD cycles at work recently. As is the way in modern software development, the topic of LLMs and Agentic programming came up and how they work alongside TDD. I gave a quick answer, but I thought it best to expand on my thoughts slightly.

When LLMs first became popular for programming, I often saw developers shouting with glee about how they no longer needed to write tests. It was a worrying development, because I find writing tests such an important step to designing code; I thought that the glee of not writing tests would subside, but it never did.

Tests are really important for humans to write, especially when following TDD. Developers often dislike writing tests, but I have always found them a joy to write. The more I utilised TDD in my development process the more I found it critical for a human to write tests.

From my aforementioned blog post on TDD, I summarised TDD cycles as:

Red: Write a test. It won't pass.

Green: Get that test passing as quickly as possible.

Refactor: Make the code that made the test pass well engineered, nice and clean.

The red step is all about making you focus on your interfaces and general code design. Without developers writing the tests themselves, and therefore not having that isolated focus on design, I find that developers think about the design less, whereas TDD cycles allow for rapid seamless dedicated code design steps.

The green step - getting tests to pass as quickly as possible without consideration for code quality - is where coding agents shine. Just get an agent to get the test to pass as quickly as possible! That is completely acceptable in TDD land and agents are excellent at that sort of task! You just need to make sure that the pass is valid and that the code has the intended functionality. Using agentic programming for this step is the greatest gain from agentic programming in TDD.

Finally you have the refactor step. Personally, I like going through and refactoring the agents' work myself; it helps me review and understand what the agent has written, whilst providing the opportunity to improve maintainability, readability and follow best practices.

You can use an agent for the refactor step. I don't, because I find that it adds an extra step to the agentic TDD cycle. The developer still has to review the refactor before going back to the red step, whereas this would not be necessary if a human were to complete the refactor step. Using an agent for this step also reduces my feeling of ownership and stewardship of the code I am responsible for.

We could have a "red, green, refactor, review" cycle. To maintain the perks of thinking about code design and maintaining a developer's connection to the code they write, I feel that a more traditional - yet agentic powered - cycle, which remains largely the same, is sufficient:

  1. Red (Human): Write a test. It won't pass.
  2. Green (Agentic): Get that test passing as quickly as possible.
  3. Refactor (Human): Make the code that made the test pass well engineered, nice and clean.