When it's time to clean up and refactor a messy piece of legacy code, we often feel safe seeing all our tests pass. But here's the kicker: those passing tests might just be an illusion! A characterization test that cannot fail is merely «decoration,» not a true «safety net,» and that's the core point.

Many messy-repo refactors fail the same way: you record golden values (the current expected output of the code), all tests pass, and you feel secure. Then you extract a function or change a piece of code, only to later discover you've shipped a silent behavior change without realizing it. The golden values never noticed because they were never able to notice. This happens because our test suites might be asserting on empty results, swallowed exceptions, or stubs that never actually run.

So, what does this mean for you? To make your code refactoring safe and effective, follow this simple workflow:
First, record the current behavior of the code (the golden values).
Second, and most importantly, prove each recorded case can fail. How? Introduce a deliberate, minimal mutation into the code under test, and confirm that the specific test case fails. This is the critical step that earns your tests' trust.
Third, only once you are confident your tests can catch errors, make the smallest safe change to the code.

Remember, golden values freeze what the code does today, including its bugs. And that's the point. But a passing test proves nothing on its own. A test only earns trust when you can make it fail on purpose. If your messy functions hide collaborators like time, randomness, network calls, or global writers, tackle these «seams» within your test harness first, before you even begin refactoring. These patches are temporary and live in your test code. This approach ensures your tests are truly a safety net, not just decoration.