It can at first be difficult to see the immense advantages arising from using this method of testing over a more quick-and-dirty method involving the server error log, such as the one we somewhat contemptuously described earlier.
There are four core benefits. First, the black box that your test suite will become will allow you to effectively regression test your class should you make changes to it later in the project. Second, your test suite will become a jack-of-all-trades hammer that you can use in myriad situations on your project with very little modification. Third, this form of formal testing provides a degree of demonstrable quality assurance that informal use of debug statements cannot ever hope to match. Finally, the inevitable burden of functional testing is lessened when a formal test plan involving frameworks has been followed.
The next sections look at these benefits in more detail.
The vast majority of code you'll ever work on will, at some stage, need to evolve. It may not necessarily be you who works on it, but you can lay money on its not staying untouched for too long.
You might need to rework an existing method to make it provide exactly the same functionality as it did before but with a big performance increase. The only way to do this is to completely rewrite the method, keeping the interface the same but with an optimized inner algorithm. In this kind of example, your testing suite is immensely useful. Simply run it before and after your new algorithm has been developed, and check that you get the same results both times.
A more likely scenario, however, is that your class needs to be extended with a new method to support some new business requirement. Even then, your testing suite is useful in its unmodified form. You can ensure that your new method does not in any way impact the functionality of any other methods. After verifying this, you can simply extend your test case class to test your new method.
Either way, you can see that using unit test frameworks for this kind of testing, commonly known as regression testing, makes good sense.
Your test case classes may have wider uses than you think. Other classes you develop with similar or identical interface functionality can be quickly and reliably tested using your existing test suites.
In particular, you may have inherited classes that overwrite the functionality of their parent class. Alternatively, taking advantage of PHP 5's new object model, you may have classes that implement abstract interfaces. A good example of this is objects representing entities stored in a database, which will almost certainly have getProperty, setProperty methods, and so forth. With little or no adaptation, a standard test suite can be used to provide an instant and reliable commentary on the functionality of such classes.
A professional software development environment can often contain a complex hierarchy of individuals involved on any given project; from the project manager right through to the lead architect, the software engineers, the designers, and others.
In this kind of environment, literally tens of thousands of lines of code can be churned out every single day. It is simply impossible for the project's lead architect to test every single component his or her developers produce.
With this kind of structured testing methodology, the management buzzword of empowerment becomes an achievable reality. That is to say, engineers can be safely trusted to test their own code, because this methodology encourages a thoroughness that is often absent in other, more haphazard component-testing techniques. Lead architects can easily standardize quality assurance across all component production and have far greater confidence in his or her team's output as a result.
The formal nature of this process is likely to be viewed favorably by nontechnical individuals with a keen interest in the progress of a project, such as project and account managers.
It's often said that the least sexy part of the project life-cycle is functional testing. Whether this statement is fair or not, it is certainly an additional cost that needs to be borne and budgeted for.
By requiring the development team to take ownership of the functional testing of its own components, the need for exhaustive and extensive functional testing of the completed application can be greatly reduced.It is not eliminated entirely, however, and as you will learn in Chapter 23 it is still vitally important.