Refactoring & Code Quality
Refactoring & Testing Safety
Refactoring is only as safe as the test suite underneath it: tests are what turn "I'm fairly sure this is equivalent" into "I verified this is equivalent." Without them, the same edits are just changes made on faith.
- A regression suite is the harness that makes small, frequent refactoring steps verifiable rather than hopeful
- Legacy code with no tests needs characterization tests first — tests that pin down current behavior (bugs included) before anything is restructured
- Red-Green-Refactor (from TDD, see Testing Philosophy) is refactoring's most disciplined form: never restructure and add behavior in the same step
- Coverage percentage is a floor, not a guarantee — 100% coverage with weak assertions can still miss a broken refactor
- Mutation testing (deliberately introducing small bugs and checking the suite catches them) measures whether tests actually assert something, not just execute the code
A characterization test doesn't test "correct" behavior — it tests current behavior, quirks and all, so that a refactor of unfamiliar legacy code has something to check itself against. Write the test, run it against the untouched code, and record whatever it produces as the expected result — even if that result looks wrong. Only after the refactor is safely underway, with the suite green throughout, does fixing the actual bug become a separate, deliberate step.
| Step | Rule |
|---|---|
| Red | Write a failing test for the next tiny bit of behavior — nothing else |
| Green | Write the simplest code that makes it pass — no more |
| Refactor | Clean up the result with tests green throughout — no new behavior added here |