Using PHPUnit

Using PHPUnit

This section covers how PHPUnit implements the concepts of test suites and test cases, putting theory into practice.

By first writing a test case for your class, you can then easily develop a test suite to provide a black-box test mechanism that you can be use repeatedly to test your class, even after you've made major changes to the underlying code of that class.

Test Cases

Take a look at how to create a test case using PHPUnit.

We assume that you have a test class saved in a separate file, testclass.phpm. Because you're still looking at the theory of PHPUnit, it doesn't matter too much at this stage what's in that class. Something similar to the following will suffice for now:

   <?php    class TestClass {     private $testVar;     function myMethod($strParam) {      $this->testVar = $strParam;      return('expected result');     }    }; 

You can now create the test case in separate PHP file, testcase.phpm.

The first two lines of the test case should include both the necessary PHPUnit class and the test class file(s):

   require_once("testclass.phpm");    require_once("PHPUnit.php"); 

Assuming that you used PEAR to install PHPUnit, it should be able to find PHPUnit.php just fine. If not, and you had to install it manually, you may have to help PHP out by pointing it to the correct file, as follows:


In this case, PHPUnit is installed in /home/ed/myphplibs.

Now take a look at how to extend the PHPUnit_TestCase class to form your very own test case with some pseudocode:

   class MyTestCase extends PHPUnit_TestCase    {        var $objMyTestClass;        function __construct($name) {           $this->PHPUnit_TestCase($name);        }        function setUp() {            $this->objMyTestClass = new TestClass();        }        function tearDown() {            unset($this->objMyTestClass);        }        function testMyMethod() {            $actualResult = $this->objMyTestClass->myMethod('parameter');            $expectedResult = 'expected result';            $this->assertTrue($actualResult == $expectedResult);        }    } 

You can now go through this step by step.

   class MyTestCase extends PHPUnit_TestCase 

Name the class whatever you want. Make sure that it extends PHPUnit_TestCase, however.

   var $objMyTestClass; 

The only member variable your extended test case class needs is a single instance of your test class. However, in more complex situations you may want to use multiple instances of the same class, or even more than one class. You should try to keep the number of classes involved in any given test case to a minimum, however, for simplicity's sake. Certainly, you should never group unrelated classes together in a single test case.

   function __construct($name) {       $this->PHPUnit_TestCase($name);    } 

The constructor for your extended test case class falls here. Its only job is to call its parent constructor. Note the non-optional $name parameter, however, which is used by the test suite class:

   function setUp() {        $this->objMyTestClass = new TestClass();    }    function tearDown() {        unset($this->objMyTestClass);    } 

These two methods are best described as virtual constructors and destructors. These are called before and after the various test functions are executed. Usually, their only job is to instantiate a working instance of your test class into the member variable you defined earlier.

   function testMyMethod() {        $actualResult = $this->objMyTestClass->myMethod('parameter');        $expectedResult = 'expected result';        $this->assertTrue($actualResult == $expectedResult);    } 

This is where the real meat of your test case is defined. Declare one method for each method of your test class that you want to test. The method must begin with the word test for it to be automatically executed by the test suite. You should name the method test followed by the name of the real method in your test class. This makes things a great deal clearer if you need to look at the test case again.

The actual functionality of this method is largely up to you. Ultimately, however, you will be doing four things. First, you will be declaring (that is, hard-coding) or determining a test parameter to pass into your test class's method. Second, you will be declaring or determining the expected result based on that parameter. Third, you will be calling the method with that parameter and capturing the actual result. Finally, you will be comparing the actual result to your hypothesis.

That comparison should be done using one of a number of assertion methods provided by PHPUnit. It is these assertions that allow the test suite to report test results. Essentially, it is the accuracy of your assertions that will be reported.

Numerous assertion methods are available assertEquals, assertTrue, assertFalse, assertNotNull, assertNull, assertSame, assertNotSame, assertType, and assertRegExp. They pretty much all do exactly what you'd expect from their name, but if you're curious, check out /usr/local/lib/php/PHPUnit/Assert.php, or the file Assert.php in the directory in which you installed PHPUnit, for definitive answers.

You may be wondering why having so many assert methods is necessary. Surely all comparisons can be handled using assertEquals and making liberal use of appropriate built-in PHP functions? This is true. It's really just a convenience to make your code a little easier to read, and to let you avoid using double negatives and so forth. In later versions of PHPUnit, the assertions actually provide assertion-specific details with any failed test (such as showing the two types in question in assertType, and which characters don't actually match when comparing two strings).

The Test Suite

Having developed your test case class, using it in a test suite is actually a relatively simple mechanism. You might name the following testsuite.php:

   <?php    require_once 'testcase.php';    require_once 'PHPUnit.php';    $objSuite = new PHPUnit_TestSuite("MyTestCase");    $strResult = PHPUnit::run($objSuite);    print $strResult->toString();    ?> 

You need to replace MyTestCase with the actual name of your test case class. If you run this from the command line (as opposed to using your Web browser), you'll get output that looks something like this if things worked:

   TestCase objMyTestClass->myMethod() passed 

It will look like this if things didn't work:

   TestCase objMyTestClass->myMethod() failed: expected true, actual false 

Note that if you want to run in a Web browser rather than at the command line, you should use the toHTML rather than the toString method on the output string so that carriage returns get converted to <br /> and so forth.

As you can see, constructing a simple test unit is a pretty simple exercise. But why would you bother in the first place, and how do you go about implementing this methodology to test a real-world class? The next section should answer these questions.

Professional PHP5 (Programmer to Programmer Series)
Professional PHP5 (Programmer to Programmer Series)
Year: 2003
Pages: 182
BUY ON AMAZON © 2008-2017.
If you may any questions please contact us: