>It completely breaks down as soon as you get into your first refactoring that is a bit larger than completely trivial.
This is, in fact, MUCH easier to do with a strong test suite that only cares about input and output rather than internals.
The most common approach to starting a refactoring project is write or enhance a test suite to the point where there is no undefined behavior, either the program works or handles the appropriate errors.
You don't need to aim for 100% test coverage either, you just need your tests to cover all possible inputs (including fuzzing).
This is, in fact, MUCH easier to do with a strong test suite that only cares about input and output rather than internals.
The most common approach to starting a refactoring project is write or enhance a test suite to the point where there is no undefined behavior, either the program works or handles the appropriate errors.
You don't need to aim for 100% test coverage either, you just need your tests to cover all possible inputs (including fuzzing).