PHP Objects, Patterns and Practice (3rd edition)

(Barry) #1

■Chapter 18: Testing with PHPUnit .....................................................................


and fails as it should. The objective, as far as possible, is to test each component in isolation from its
wider context. This often supplies you with a sobering verdict on the success of your mission to decouple
the parts of your system.
Tests can be run as part of the build process, directly from the command line, or even via a web
page. In this chapter, I’ll concentrate on the command line.
Unit testing is a good way of ensuring the quality of design in a system. Tests reveal the
responsibilities of classes and functions. Some programmers even advocate a test-first approach. You
should, they say, write the tests before you even begin work on a class. This lays down a class’s purpose,
ensuring a clean interface and short, focused methods. Personally, I have never aspired to this level of
purity—it just doesn’t suit my style of coding. Nevertheless, I attempt to write tests as I go. Maintaining a
test harness provides me with the security I need to refactor my code. I can pull down and replace entire
packages with the knowledge that I have a good chance of catching unexpected errors elsewhere in the
system.


Testing by Hand


In the last section, I said that testing was essential in every project. I could have said instead that testing
is inevitable in every project. We all test. The tragedy is that we often throw away this good work.
So, let’s create some classes to test. Here is a class that stores and retrieves user information. For the
sake of demonstration, it generates arrays, rather than the User objects you'd normally expect to use:


class UserStore {
private $users = array();


function addUser( $name, $mail, $pass ) {
if ( isset( $this->users[$mail] ) ) {
throw new Exception(
"User {$mail} already in the system");
}


if ( strlen( $pass ) < 5 ) {
throw new Exception(
"Password must have 5 or more letters");
}


$this->users[$mail] = array( 'pass' => $pass,
'mail' => $mail,
'name' => $name );
return true;
}


function notifyPasswordFailure( $mail ) {
if ( isset( $this->users[$mail] ) ) {
$this->users[$mail]['failed']=time();
}
}


function getUser( $mail ) {
return ( $this->users[$mail] );
}
}

Free download pdf