The post (“The co-evolution of AI coding and unit testing: from verification to driving”) argues that unit tests are the fastest way to check the quality and reliability of code produced by AI coding assistants. It names two risks that set AI-generated code apart from hand-written code: its quality depends on the context and on the model’s own capability and is relatively uncontrollable, and code that reads as logically coherent and structurally complete can still hide boundary problems or logic defects that are hard to notice. From these it derives three pain points — judging large amounts of generated code by eye, trusting AI when it modifies existing code, and conveying complex requirements to the AI precisely — and answers each with a different unit-testing strategy, illustrated with Java examples from the team’s own business code.
The post closes by recasting unit testing from a “development burden” into the “quality engine” of AI coding, and the developer’s role from a passive reviewer of AI code into an active designer of requirements and owner of quality — a shift it describes as moving from “thinking about prompts” to “thinking about test cases”.
Key Points
- Skipping unit tests and going straight to integration testing only pushes risk later: the post invokes shift-left testing and argues that a bug found in minutes during development can, in an integration environment, take a long chain of deployment, environment preparation, diagnosis, fixing and redeployment to resolve.
- Strategy one uses unit tests, written with AI help, to verify AI-generated logic instead of reviewing it by eye. In its paged-query example, 17 such tests exposed a filter that compared a Boolean field with an Integer, so the query returned no results when the
enabledflag was set — a defect the post says was very hard to spot by reading; reviewing the code under test also surfaced an N+1 query performance problem. - Strategy two brings existing logic fully under unit-test coverage before AI is allowed to change it, which the post likens to fastening a seat belt before switching on driver assistance. A passing baseline is run first; after the AI’s change, failing tests separate expected failures (logic deliberately changed) from unexpected ones (existing behavior broken). In its example — extending a delayed-reply feature to a third platform’s users — one expected failure was updated and the remaining tests stayed green.
- The post classes the first two strategies as “generate first, verify later” and says they still leave developers repeatedly rewriting natural-language prompts and checking generated test cases by hand.
- Strategy three applies TDD’s red-green-refactor cycle so that tests serve the AI as an unambiguous requirements specification and acceptance criteria. In its coupon-rule-engine example, three rounds of natural-language prompting produced implementations that missed the stacking and mutual-exclusion rules; failing tests encoding those rules led the AI to an implementation that passed them, which was then refactored under the tests’ protection. The developer defines “what” and the expected results; the AI supplies the “how”.
- For TDD-driven generation, the agent must be able to run the test command itself, and a rules file should state the development paradigm so that the AI does not “cheat” by modifying business code just to get tests to pass. The post’s example rules file restricts each phase: in red the agent may add tests but not modify existing code under
src/main/, in green it may change implementation code but not the tests, in refactor it may restructure implementation code without changing the tests’ behavior or expectations, and it must announce which phase it is entering. - AI is described as good at covering basic test cases, while complex business scenarios and boundary conditions may still need tests written by the developer.
- The post’s decision rule: simple, single-method functions — implement first, then verify; complex business logic with many branches, algorithmic calculation or state transitions — TDD; changes to existing code — the safety-net strategy; requirements that are hard to express in a prompt — TDD, with test cases as the requirements document.
- Unit tests must evolve together with the business code; an outdated, unmaintained test suite quickly loses its value and can become a liability.
Context
The three strategies are presented as the team’s own working practice, each illustrated by a single worked example rather than a measured comparison. The post’s third strategy is an application of Red/Green TDD to directing an AI coding agent, and its opening argument draws on the testing sense of Shift Left.