Pin the Behaviour With Tests Before You Refactor
What it is
A refactoring pattern where, before changing any structure, you have Claude write characterization tests that capture what the code currently does — including its quirks — so you can restructure with a green suite proving you changed nothing observable.
Why it works
Refactoring means changing structure without changing behaviour, but you can only know behaviour is unchanged if something checks. Untested refactors are just hopeful rewrites. Characterization tests turn 'I think this still works' into 'the suite says it does'. Claude is fast at reading existing code and generating tests that lock in its present output, giving you the net before you climb.
When to use it
Refactoring code that lacks tests, especially legacy or inherited code you don't fully understand. The less you trust the code, the more you need the net first.
When not to use it
Code that already has strong behavioural tests — you can refactor directly and lean on them. And don't characterize code you're about to delete or rewrite from scratch; you'd be pinning behaviour you don't want to keep.
Prompt
I want to refactor this code but it has no tests: <paste>.
Before any refactor, write characterization tests that capture its current behaviour exactly — including edge cases and any surprising outputs — so I have a safety net. Don't fix bugs yet; if you notice one, capture the current (buggy) behaviour and flag it separately. Then I'll refactor and we confirm the suite stays green.Example
Facing a gnarly pricing function, Claude writes fifteen tests covering the tiers and two odd rounding cases. One test documents a rounding quirk you didn't know about. You refactor the tangle into three clear steps; the suite stays green — including the quirk — so you know the change is purely structural, and you fix the quirk later as its own visible change.
Advanced version
Have Claude generate the characterization tests by feeding real inputs through the current code and snapshotting outputs, then review the snapshots for anything that looks wrong. The review step turns test-writing into a free audit of behaviour you were about to preserve.
Common mistakes
- Fixing bugs during the characterization step — now the tests describe behaviour the code doesn't have, and you can't tell a refactor break from the fix.
- Writing tests against the implementation details you're about to change, so they break on the refactor and prove nothing.
- Refactoring and characterizing in the same commit, so a red test can't tell you which move caused it.