Legacy code (often untested, hard-to-change code) is challenging to test — it may have tangled dependencies and no tests. Adding tests safely involves techniques like characterization tests, seams for breaking dependencies, and incremental improvement, enabling safer changes.
The challenge of legacy code
Legacy code is often: untested, tightly coupled, hard to understand, risky to change:
→ no tests → changing it is dangerous (you can't tell if you broke something)
→ hard to test → dependencies are tangled (can't isolate units); not designed for testing
→ a chicken-and-egg problem: to change safely you need tests, but it's hard to test.
