Refactor a Messy Repo Without Breaking It: Characterization Tests, Then the Smallest Safe Change
Description and use
Use characterization tests to capture the behavior of a complex module, then refactor incrementally without breaking functionality.
Problem
A legacy pricing module is 900 lines, undocumented, and has no tests, making any change risky and leading to production rollbacks.
Outcome
Characterization tests captured the existing behavior of a 900‑line pricing function, allowing the team to refactor incrementally without breaking production. The approach turned a risky rewrite into a controlled, test‑driven process.
Workflow
- Identify high‑churn, high‑branch files with
git log --oneline -- <file>andradon cc <file> -s - Add a lightweight recording decorator to the target module and enable it via
CHAR_CAPTURE=1 - Run normal workflows to exercise the module, generating
recordings.json - Create a pytest replay harness that turns each recorded call into a test case
- Run the test suite; any failure indicates an unknown behavior that must be understood before further changes
- Iteratively refactor small parts of the module, running tests after each change to ensure no new failures
- Repeat until the module is refactored or replaced with a cleaner implementation
Evidence
A characterization test captures what the code does today without judging whether that behavior is correct.
Drop the decorator into the messy module, run your normal workflows, and the suite freezes whatever you just executed.
- Record date: 2026-09-09T14:15:15.382Z