Legacy code and behaviour-preserving migration
পুরোনো code আগে বুঝে test-এ ধরো। একবারে rewrite করলে আসল নিয়ম হারিয়ে যেতে পারে।
Guess first
Pick an answer. You will see if you were right at the end of the lesson.
What undocumented behaviour could disappear?
Real-world analogy
What is it?
Legacy systems often contain business knowledge that is absent from documentation. Characterisation tests record current behaviour before refactoring. Some current behaviour is a bug; label it explicitly and agree on the desired change rather than accidentally preserving or deleting it.
Real-world relevance
One shared support-ticket product, three optional entry points. Frontend: Characterise an old form component before replacing its state library. Backend: Characterise a legacy endpoint before changing its query or response mapping. Mobile: Characterise the sync adapter before replacing persistence or navigation.
Key points
- Find one seam — Choose a narrow function or adapter that can be replaced independently.
- Record behaviour — Capture normal, edge and error outputs using synthetic fixtures.
- Distinguish bug from contract — Write down which behaviour must stay and which intentionally changes.
- Use adapters — Keep old callers stable while introducing a new implementation.
- Avoid dual-write surprises — Migration retries need idempotency and a reconciliation plan.
- Keep branches separate — Do not bulk-copy unrelated platform changes or cross known branch boundaries.
- Prove rollback — Verify both old and new paths against the same relevant cases.
- Frontend practice — Characterise an old form component before replacing its state library.
- Backend practice — Characterise a legacy endpoint before changing its query or response mapping.
- Mobile practice — Characterise the sync adapter before replacing persistence or navigation.
Quick check
Answer from memory — scrolling up first makes it stick less.
What artifact demonstrates this lesson?
Which statement is defensible?
Code example
def legacy_label(code):
return {0: "queued", 1: "saved"}.get(code, "unknown")
def test_characterisation():
assert legacy_label(0) == "queued"
assert legacy_label(1) == "saved"
assert legacy_label(99) == "unknown"Line-by-line walkthrough
- 1. Python: unknown input is an explicit recorded behaviour. A replacement that throws for 99 changes the contract and needs a deliberate decision.
Spot the bug
Rewrite the whole module and trust the new architectureNeed a hint?
Show answer
Explain like I'm 5
Fun fact
Hands-on challenge
More resources
- Building effective agents (Anthropic)
- Download the free offline lab (Python, tests and instructions) (Teamz Lab)
Lock it in