Test-Driven Generation (TDG): Adopting TDD again this time with Gen AI

Chanwit Kaewkasi
6 min readSep 14, 2024

--

In past years, software development has seen an evolution with the introduction of new tools and methodologies that aim to streamline processes and improve code quality. One of the most influential methodologies has been Test-Driven Development (TDD). It’s a practice where developers first write the test cases for functionality before implementing the actual code.

But from my own experiences, I have to admit that TDD is hard!

Its down side is that TDD requires time to practice and master the technique. However, the rise of Generative AI opens new possibilities for further improving this technique. Combining TDD, Pair Programming, and Generative AI, I’d like to propose a new approach: Test-Driven Generation (TDG).

What the heck is Test-Driven Generation?

TDG is an alternative development practice that integrates generative AI directly into the development life-cycle.

Instead of human developers writing both tests and code, the developer acts as a specifier who outlines the requirements and specifications, while the AI generates the corresponding tests and code.

Well, many of us have been already doing that!

But TDG is still based on the familiar principles of TDD, with a twist: the developer pairs with a generative AI model. This AI takes over the role of generating test cases and even code, leaving the developer to focus on higher-level specifications and logic.

The process works as follows:

  • Spec Definition: The developer provides a high-level specification or user story to the AI for test generation.
  • Test Generation: The AI generates the relevant test cases based on the provided specifications.
  • Test Execution: The developer runs the tests, which should fail initially since no code exists to pass them yet.
  • Spec Definition for Code: This time provides a specifiction for code generation.
  • Code Generation: Based on feedback from the failing tests and refined specs, the AI generates code to meet the test requirements.
  • Test Re-run: The developer re-runs the tests. If the tests pass, the cycle proceeds; if not, the AI refines the code until all tests pass.
  • Iteration: The process iterates with the developer adding new specs, and the AI continuing to generate additional tests and code, until the entire program is fully developed.

You can really see that the loop is just slightly different from the way we’re currently using AI to generate code. This process still requires a little discipline from TDD, which is generating the test first, then code later.

Benefits of TDG

Combining the strengths of generative AI with traditional development practices, TDG offers many advantages over conventional methodologies like TDD and pair programming. Many benefits are inherited from the use of TDD.

Faster Iterations: TDG accelerates the development cycle by offloading the task of writing code and tests to the AI. We can focus on refining specifications and overseeing the development process rather than manually handling every coding detail.

Higher Quality Code: Since the AI generates test cases from the very start, the code is inherently designed to meet those tests. This reduces the risk of missing edge cases or producing buggy code.

Continuous Feedback Loop: TDG provides a constant feedback loop, where developers see test results immediately after the AI generates code. This allows for quick course corrections, ensuring that the code aligns with the evolving specifications. This would also help solve the non-deterministic part of AI code generation.

Less Cognitive Load on Developers: Of course, using Generative AI is known to help reduce cognitive load. Developers can focus on high-level design, architecture, and strategic problem-solving while allowing the AI to handle routine tasks like writing test cases and boilerplate code. This reduces developer fatigue and allows us to be more productive in the long term.

Addressing Cons of TDD

Many teams I knew failed to adopt TDD because the technique had its own problems. But with TDG, it can address several of these key cons of TDD by leveraging Generative AI to automate many parts of the process. Here’s how TDG could mitigate the major drawbacks of TDD:

Slower Initial Development

  • TDD Con: Writing tests before writing the code adds overhead in the early stages of development, slowing down the overall progress.
  • Solution: With Generative AI, the AI can automate test creation based on high-level specifications provided by the developer. This eliminates much of the manual work involved in writing tests upfront, significantly reducing the time needed to start development. Instead of writing each test case manually, the developer focuses on refining specs while the AI generates relevant tests​.

Test Maintenance

  • TDD Con: As project requirements evolve, tests need to be updated frequently. This can make maintaining a large test suite burdensome, especially if tests are not written or maintained properly.
  • Solution: The AI in TDG can automatically adjust test cases when specifications change, reducing the need for developers to manually rewrite or adjust the tests. This makes test maintenance more manageable by having AI adapt to changes quickly, ensuring that the tests stay aligned with evolving functionality​.

Steep Learning Curve

  • TDD Con: TDD requires developers to have experience in writing effective tests, which can be difficult and time-consuming to learn, especially for those new to the methodology.
  • Solution: TDG reduces the learning curve by delegating the test-writing task to the AI. Developers don’t need to master the art of test case writing to the same extent. They can focus on high-level design and logic, allowing AI to handle the complexities of generating comprehensive test cases​.

Requires Discipline and Team Buy-in

  • TDD Con: Successful TDD requires a high level of discipline and consistent practice from the entire team. If even a few team members don’t follow the methodology rigorously, the benefits of TDD diminish.
  • Solution: TDG automates a significant portion of the process, reducing the need for strict discipline. The AI can generate tests consistently, ensuring that no steps are skipped. This allows the team to focus on refining code and design while the AI maintains a consistent testing framework. TDG reduces the dependency on human discipline by making certain tasks automatic​.

Why should we consider TDG when Gen AI can already generate code?

  1. Ensuring Higher Code Quality and Reliability
    While Generative AI can quickly produce code, it doesn’t inherently guarantee that the code is correct, reliable, or meets all specified requirements. TDG incorporates the creation of test cases before code generation, ensuring that the AI-generated code is validated against these tests. This approach catches bugs and edge cases early.
  2. Structured Development Process
    TDG provides a structured workflow that integrates the principles of Test-Driven Development with Generative AI. This process ensures that development follows a clear specification-to-test-to-code sequence of TDD but now AI-powered.
  3. Reduced Debugging Time
    Generating tests first, TDG helps identify issues at the earliest stage of development. This proactive approach reduces the time developers spend on debugging and fixing errors after the fact. Simply generating code without accompanying tests can lead to more time spent diagnosing problems later.

In summary, Test-Driven Generation (TDG) blends the best of Test-Driven Development (TDD), Pair Programming, and Generative AI to improve the development process. Instead of writing both the tests and code ourself, we give the AI the specs, and it generates the tests and the code that passes them. This means we get clean, well-tested code faster, while keeping the benefits of TDD to cut down on time spent debugging and fixing confusing errors.

Would you like to try this TDG technique? Let me know in comments!

--

--

Chanwit Kaewkasi

Tech Advisor at ConfigHub. ex @weaveworks. Go nut since r57 (pre v1)