TABLE OF CONTENTS (HIDE)

PHP Unit Testing with PHPUnit

Introduction

Various type of software testings:

  • Unit Test: Test individual component/class in isolation.
  • Integration Test: Test a group of associated components/classes.
  • Acceptance Test (or Functional Test): operate on a fully integrated system, testing against the user interface (e.g., HTML for browser or XML/JSON for web services).
  • Regression Test: Tests to ensure the a change (such as enhancement, patches or configuration change) does not break the system or introduce new faults.

PHP unit testing frameworks:

PHP Acceptance test frameworks:

PHPUnit

"Unit testing allows you to write small test methods which verify units of functionality in your program. It is a powerful technique for improving the quality of your software, preventing regressions, and allowing confident refactoring of your code."

"PHPUnit is a unit testing suite for the PHP language, modeled on the xUnit testing framework, designed by Kent Beck and Erich Gamma. If you've used JUnit (for Java), PyUnit (for Python), CxxUnit (for C++), or any of the other equivalents for other languages, the API for this package should seem fairly familiar. If you've never written unit tests before, the PHPUnit API is simple to learn and use."

Installing PHPUnit

On Ubuntu:

$ sudo apt-get install phpunit

Getting Started with Examples

Read "PHPUnit Manual" @ http://phpunit.de/manual/current/en/index.html, which is extremely extensive.

Example 1:

Suppose that you have written the PHP array, and need to do unit test for the array and its functions count(), array_push(), array_pop().

Write the following PHPUnit test script called "ArrayTest"

<?php
class ArrayTest extends PHPUnit_Framework_TestCase {
   public function testPushAndPop() {
      // Allocate a test fixture.
      $fixture = array();
      // Assert initially empty, count() is 0.
      $this->assertEquals(0, count($fixture));

      // Test array_push().
      // Push an item into array.
      array_push($fixture, 'foo');
      // Assert one item, count() is 1.
      $this->assertEquals(1, count($fixture));
      // Assert item pushed.
      $this->assertEquals('foo', $fixture[count($fixture)-1]);
 
      // Test array_pop().
      $this->assertEquals('foo', array_pop($fixture));
      $this->assertEquals(0, count($fixture));
   }
}
?>

To run the test:

$ phpunit --verbose ArrayTest.php
PHPUnit 3.6.10 by Sebastian Bergmann.
.
Time: 0 seconds, Memory: 3.00Mb
OK (1 test, 5 assertions)

The dot (.) represents ONE test passed.

To show you what happens if the test fails, we modify the test script for array_pop() (we can't change the array!) as follows:

<?php
class ArrayTest extends PHPUnit_Framework_TestCase {
   public function testPushAndPop() {
      // Allocate a test fixture.
      $fixture = array();
      // Assert initially empty, count() is 0.
      $this->assertEquals(0, count($fixture));

      // Test array_push().
      // Push an item into array.
      array_push($fixture, 'foo');
      // Assert one item, count() is 1.
      $this->assertEquals(1, count($fixture));
      // Assert item pushed.
      $this->assertEquals('foo', $fixture[count($fixture)-1]);
 
      // Test array_pop().
      $this->assertEquals('bar', array_pop($fixture));
      $this->assertEquals(0, count($fixture));
   }
}
?>

Run the test again:

$ phpunit --verbose ArrayTest.php
PHPUnit 3.6.10 by Sebastian Bergmann.
F
Time: 0 seconds, Memory: 3.00Mb

There was 1 failure:
1) ArrayTest::testPushAndPop
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'bar'
+'foo'

ArrayTest.php:18

FAILURES!
Tests: 1, Assertions: 4, Failures: 1.

The 'F' represents ONE test failed, with the details of the failure.

Example 2:
<?php
class ArrayTest extends PHPUnit_Framework_TestCase {
    public function testEmpty() {
        $fixture = array();
        $this->assertEmpty($fixture);
        return $fixture;
    }
 
    /**
     * @depends testEmpty
     */
    public function testPush(array $fixture) {
        array_push($fixture, 'foo');
        $this->assertEquals('foo', $fixture[count($fixture)-1]);
        $this->assertNotEmpty($fixture);
        return $fixture;
    }
 
    /**
     * @depends testPush
     */
    public function testPop(array $fixture) {
        $this->assertEquals('foo', array_pop($fixture));
        $this->assertEmpty($fixture);
    }
}
?>

Run test:

$ phpunit --verbose ArrayTestDepends.php
PHPUnit 3.6.10 by Sebastian Bergmann.
...
Time: 0 seconds, Memory: 2.75Mb
OK (3 tests, 5 assertions)

REFERENCES & RESOURCES

  1. PHPUnit Manual @ http://phpunit.de/manual/current/en/index.html.