PHP Objects, Patterns and Practice (3rd edition)

(Barry) #1

C H A P T E R 18


■ ■ ■


Testing with PHPUnit


Every component in a system depends, for its continued smooth running, on the consistency of
operation and interface of its peers. By definition, then, development breaks systems. As you improve
your classes and packages, you must remember to amend any code that works with them. For some
changes, this can create a ripple effect, affecting components far away from the code you originally
changed. Eagle-eyed vigilance and an encyclopedic knowledge of a system’s dependencies can help to
address this problem. Of course, while these are excellent virtues, systems soon grow too complex for
every unwanted effect to be easily predicted, not least because systems often combine the work of many
developers. To address this problem, it is a good idea to test every component regularly. This, of course,
is a repetitive and complex task and as such it lends itself well to automation.
Among the test solutions available to PHP programmers, PHPUnit is perhaps the most ubiquitous
and certainly the most fully featured tool. In this chapter, you will learn the following about PHPUnit:



  • Installation: Using PEAR to install PHPUnit

  • Writing Tests: Creating test cases and using assertion methods

  • Handling Exceptions: Strategies for confirming failure

  • Running multiple tests: Collecting tests into suites

  • Constructing assertion logic: Using constraints

  • Faking components: Mocks and stubs

  • Testing web applications: With and without additional tools.


Functional Tests and Unit Tests


Testing is essential in any project. Even if you don’t formalize the process, you must have found yourself
developing informal lists of actions that put your system through its paces. This process soon becomes
wearisome, and that can lead to a fingers-crossed attitude to your projects.
One approach to testing starts at the interface of a project, modeling the various ways in which a
user might negotiate the system. This is probably the way you would go when testing by hand, although
there are various frameworks for automating the process. These functional tests are sometimes called
acceptance tests, because a list of actions performed successfully can be used as criteria for signing off a
project phase. Using this approach, you typically treat the system as a black box—your tests remaining
willfully ignorant of the hidden components that collaborate to form the system under test.
Whereas functional tests operate from without, unit tests (the subject of this chapter) work from the
inside out. Unit testing tends to focus on classes, with test methods grouped together in test cases. Each
test case puts one class through a rigorous workout, checking that each method performs as advertised

Free download pdf