Get untested code under test before changing it by pinning its current behaviour, finding a seam, and testing through the smallest boundary that works. Use when modifying legacy code, code with no tests, or code nobody understands.
---
name: test-legacy-code-safely
category: coding
description: >-
Get untested code under test before changing it by pinning its current
behaviour, finding a seam, and testing through the smallest boundary that
works. Use when modifying legacy code, code with no tests, or code nobody
understands.
---
# Test Legacy Code Safely
The trap is circular: you cannot safely change the code without tests, and you
cannot easily test it without changing it.
The way out is to **pin the behaviour you have** — including the bugs — then
refactor under that net, and only then change what the code does.
## 1. Pin current behaviour with a characterisation test
You are not asserting the code is *correct*. You are recording what it does
today, so you notice if that changes.
The trick is to let the code tell you:
```python
def test_characterise_price():
# Deliberately wrong. Run it, read the failure, paste in the real value.
assert calculate_price(items, "GOLD") == "PLACEHOLDER"
```
Run it, and the failure message hands you the actual output. Paste that in. The
test now pins the behaviour exactly.
Do this for a spread of inputs: typical, empty, zero, negative, maximum, and
whatever weird case the code obviously has a branch for.
**If you find a bug, pin the bug.** Write the test asserting the wrong-but-real
behaviour, with a comment saying it is wrong. Fixing it is a separate, visible
change — not a silent side effect of a refactor.You are reading the opening of this skill.
The rest is open to any signed-in account — free included. Reading the library costs nothing.
Shared publicly by the author and open for any use. See the Terms.