G8 Softwares / The Code You Inherit
Pin The Current Behaviour Before You Change Any Of It
Tests written to describe what a system does today are the only safe footing for changing it tomorrow.
The difficulty with modifying inherited code is not the modification, it is the absence of a way to tell whether you have broken something. Without that, every change is a wager, and the sensible response is to make as few as possible, which is exactly how a system becomes untouchable. The way out is to write tests that record what the system currently does, including the parts that look wrong. You are not asserting that the behaviour is correct. You are asserting that it is the behaviour, so that any change you make announces itself instead of leaking out into production unnoticed.
This feels strange the first time, because you find yourself carefully preserving output you suspect is a defect. Do it anyway. The distinction between fixing a bug and changing behaviour is one for a later conversation with people who know the domain, and it is a conversation you can only have once you know precisely what the behaviour is. Meanwhile the tests give you something valuable immediately: the ability to restructure with confidence, because anything you disturb will fail loudly on your own machine rather than quietly in front of a customer.
Cover the paths that matter rather than everything, since you will not get everything and pursuing it will exhaust the goodwill you need for the actual work. The paths that matter are the ones real usage exercises, the ones that handle money or produce records people rely on, and the ones near where you intend to change things. Once that net exists the system stops being frightening. It is still ugly, it still contains decisions nobody can explain, but it is now a thing you can work on rather than a thing you can only add to, and that shift is what makes an inherited system liveable.