Skip to content

TDD with AI

Disponible en francais

AI makes it easier to produce code quickly. TDD makes that speed trustworthy.

TDD with AI loop

  • AI is good at producing plausible code, not guaranteed-correct code.
  • A failing test turns vague intent into an executable contract.
  • Small red/green/refactor loops keep AI from wandering into broad rewrites.
  • Refactoring becomes safer because behavior is pinned before the model starts reorganizing code.
AreaTDD fitWhy
Services and business rulesHighLogic is compact, deterministic, and easy to verify
Routers, loaders, and actionsHighPublic contracts matter more than internal implementation
Validation, parsing, and mappersHighEdge cases are easy to miss without examples
Critical UI flowsMediumFocus on user behavior, not component internals
Pure presentational UILowManual review is often cheaper than over-testing styling

Start from the behavior you want, not from the implementation you expect.

2. Ask AI for the smallest change that makes it pass

Section titled “2. Ask AI for the smallest change that makes it pass”

Do not ask for a cleanup, optimization, and architecture rewrite in the same step.

Run the targeted test first. Then widen the verification surface if the change touches more than one layer.

Once the behavior is protected, use AI to simplify names, extract duplication, or align with existing patterns.

Grow coverage by behavior: edge cases, error paths, auth rules, null states, and retries.

Add one failing test that describes this behavior.
Keep the test focused on the public contract.
Do not change the implementation yet.
Make the smallest code change that makes the new test pass.
Avoid unrelated refactors and preserve existing behavior.
Run the targeted test after the edit.
Refactor for clarity without changing behavior.
Keep all tests green and preserve the current API.
  • Use Vitest for services, utilities, validation, and slice-level business logic.
  • Add integration tests around routers, loaders, and actions where contracts matter.
  • Keep Playwright for thin, critical end-to-end paths.
  • Avoid relying on snapshots as the primary source of confidence.

For concrete setup and examples, see the Testing Guide.

  • writing tests after the implementation and calling it TDD
  • asking for a broad rewrite instead of the next tiny step
  • accepting assertions that merely mirror the current implementation
  • relying on snapshots when behavior assertions would be clearer
  • skipping human review of the first failing test
  • behavior was expressed in a test before or during implementation
  • targeted tests passed after the change
  • the final code is simpler than the path used to reach green
  • the test protects a user-facing or contract-level behavior