ع
Start Topics Teams Reference What's new Saved
playbook

Backfill the tests you never wrote

Take a module with no tests, have Claude list the behaviours worth pinning down — including the nasty edge cases — and write a suite that covers them, flagging any latent bugs it finds on the way.

medium ~30 min
when to reach for this

Every team has the module nobody will touch — the one that's load-bearing, has no tests, and whose author is long gone, so every edit is a gamble and the safe move is to route around it forever. This system turns "untested and scary" into "covered and safe to refactor" — and the act of writing the tests usually surfaces a bug or two that were hiding the whole time, before they surface in production.

gather this first
  • The file or module you want covered — in Claude Desktop, open the project folder so Claude reads the real implementation, then point at the file in the chat.
  • How you run tests in this project — the command and the framework (vitest, pytest, go test), so the suite fits your setup.
  • Any behaviours you already know matter — the edge cases that have burned you before.
the workflow
  1. List the behaviours before writing a single test

    Open the project folder in Claude Desktop and ask in the chat — listing and writing tests needs no terminal. Don't ask for tests yet, though. Ask for the inventory of what this code is supposed to do — the happy path and, more importantly, the edges. You'll catch a missing case here.

    you ask
    Read this module. Before writing any tests, list every behaviour worth pinning down — the normal paths and the nasty edge cases (empty input, nulls, boundaries, concurrent calls, error paths). Flag anything that already looks like a latent bug.

    what you get back A checklist of behaviours grouped into happy-path and edge-case, plus a short "this looks suspicious" list — the spec the code never had written down.

    The edge-case list is the valuable part. The happy path you'd have tested anyway; the boundaries are where the bugs live.

  2. Write the suite against that list

    Now turn the inventory into real tests in your framework, named so a future reader knows what broke when one goes red. The new test file comes back as a visual diff in Desktop — review it before you accept.

    you ask
    Write a test suite covering that list using our test setup. Name each test after the behaviour it pins down, cover the edge cases explicitly, and keep each test focused on one thing. Don't change the module yet.

    what you get back A readable suite where each test maps to a behaviour from step 1 — the edge cases as their own named cases, not buried in one giant test, landing as a diff you accept in the file pane.

  3. Run it and confront the failures

    Some of the new tests may fail against the current code. That's not a bug in the tests — that's the suite earning its keep. Running your project's test command is a Power Track step (a terminal-enabled session); if you don't have one, run the suite yourself and paste the failures back into the Desktop chat — the confrontation is the same either way.

    you ask
    Run the suite. For anything that fails, tell me whether the test is wrong or the code is — don't just "fix" the test to make it pass. If it's a real bug, show me the smallest fix.

    what you get back Either green, or an honest split: "these two failures are real bugs in the module, these are my test mistakes" — with a fix proposed for the real ones, separate from the tests.

    Watch for the tempting anti-pattern: making a failing test pass by weakening the assertion. A test that can't fail protects nothing.

make it your own
  • Characterization first: for code you don't fully understand, ask for characterization tests that pin the current behaviour exactly as-is — even the quirks — so you can refactor safely before deciding what's a bug.
  • Coverage gap: point it at a coverage report — "here's the uncovered lines, write tests that exercise them" — to close specific holes rather than re-testing what's already green.
  • This green suite is a seatbelt — buckle it before the next move. The whole point of covering the scary module is what you do next: hand the now-green suite straight to the safe-refactor playbook, which runs it before and after every change so behaviour is provably unchanged. And any latent bug this surfaced doesn't get "fixed" inline — route it to the debug-from-trace playbook, where it earns its own failing-then-passing test instead of being quietly absorbed.
watch out for
  • *A test that only asserts current* behaviour can pin a bug in place.** When you backfill, you're freezing whatever the code does today — including the wrong parts. As Claude lists behaviours, make it flag the ones that look intended versus the ones that look like accidents, so you enshrine the contract and not the bug. The author of record decides which is which.
  • Don't let it make a failing test pass by softening the assertion. Ask explicitly: is the test wrong, or the code? A green suite that asserts nothing is worse than no suite.
  • Tests that just mirror the implementation line-for-line break on every refactor and catch nothing. Test behaviour and contracts, not internals.
  • Read the generated tests — a wrong test that passes encodes a wrong belief about your code and will mislead the next person.

you'll end up with A scary, untested module becomes a covered one you can change with confidence — and the act of writing the suite flushes out the one or two real bugs that were hiding in the edge cases.

Questions people ask

What do I need to gather before starting?
The file or module you want covered (open the project folder in Claude Desktop so Claude reads the real implementation — no terminal needed to read or write tests), the command and framework you use to run tests (`vitest`, `pytest`, `go test`, etc.), and any edge cases you already know have caused problems. Claude can infer a lot, but knowing your test runner up front means the suite it writes will actually fit your project.
What if some of the new tests fail against the existing code — is that a problem?
No — a failing test against existing code is the suite earning its keep, not a mistake. Running the suite is the one Power-Track step that wants a terminal-enabled session; if you don't have one, run it yourself and paste the failures into the chat. Either way, the key question to ask Claude is whether each failure means the test is wrong or the code is wrong. Never let it weaken an assertion just to turn a test green; that produces a suite that can't protect you.
How do I avoid tests that just mirror the implementation and break on every refactor?
Ask Claude to list behaviours and contracts first (step 1), then write tests against that list — not against the implementation lines. Tests named after behaviours ("returns null when input is empty") survive refactors; tests that call private methods line-for-line do not.
Can I use this to close specific gaps shown in a coverage report rather than covering a whole module?
Yes — point Claude at the coverage report and say "here are the uncovered lines, write tests that exercise them." This is faster than re-testing what's already green and works well when you have partial coverage and just want to fill the gaps.