As this is a bookprerequisites:test suite" about legacy applications, it would be the height of optimism to expect that the codebase has a suite of unit tests. Most legacy applications, especially include-oriented, page-based applications, are highly resistant to unit tests. There are no units to test, only a spaghetti mess of tightly coupled functionality.

And yet it is possible to test a legacy application. The key here is not to test what the system units ought to do, but what the system as a whole already does. The criteria for a successful test is that the system generates the same output after a change as it did before that change. This kind of test is called a characterization test.

It is not in the scope of this book to discuss how to write a characterization test suite. There are some good tools out there already for writing these kinds of tests, such as Selenium and Codeception. Having tests of this sort before we go about refactoring the codebase is invaluable. We will be able to run the tests after each change to make sure the application still operates properly.

I will not pretend prerequisites:test suite" that we are likely to spend the time writing these kinds of tests. If we were interested in testing to begin with, we would have a test suite of some sort already. The issue here is a very human one, not of doing the right thing for its own sake or even of rational expectations but of incentives based on rewards. The reward for writing tests is a longer-term one, whereas making an improvement to the codebase right now feels immediately rewarding, even if we have to suffer with manual checking of the application output.

If you have the time, the self-discipline, and the resources, the best option is to create a series of characterization tests for the parts of the application you know you will be refactoring. It is the most responsible and most professional approach. As a second-best option, if you have a QA team that already has a series of application-wide tests in place, you can delegate the testing process to them since they are doing it anyway. Perhaps they will show you how to run the test suite locally as you make changes to the codebase. Finally, as the least-professional but most-likely option, you will have to pseudo-test or spot check the application by hand when you make changes. This is probably what you are used to doing anyway. As your codebase improves, the reward for improving your own practices will become more evident; as with refactoring in general, the goal is to make things better than they were before in small increments, not to insist on immediate perfection.