Creating powerful modern websites is about so much more than simply slinging code. The complexity has become such that most gainfully employed web developers no longer create websites because the connotation is a website is a bunch of hastily slapped together "pages." Instead, we are creating web applications, with one important difference between the two being that the latter are built using a rigorous process, and with that, a rigorous testing program.
If you create web applications that talk to databases, process user input, integrate Ajax functionality, and perform other mission-critical tasks, then it's crucial that you institute a rigorous testing program -- alongside other procedures that may already be in place, such as coding standards and documentation. The PHP community has long had a great testing utility at their disposal known as PHPUnit, and in this tutorial I offer a brief introduction to its benefits.

Installing PHPUnit

PHPUnit is available as a PEAR package, meaning you can install it by simply executing the following two commands:
%>pear channel-discover pear.phpunit.de
%>pear install phpunit/PHPUnit
The above should work as written if you run Windows, however if like me you run a Linux distribution such as Ubuntu, then you'll of course need to preface these commands with sudo.
Once installed, it's time to write our first test!

Writing Your First Unit Test

A strategy known as unit testing involves writing a series tests. Each test is intended to validate the intent of a specific bit, or unit, of application code. Within these tests you make various assertions confirming whether the outcome meets expectations.
As an example, suppose you were tasked with creating a PHP application that processed Docbook files, parsing the documents to retrieve information such as the document title and author. Because of the often mind-bending nature of regular expressions, make sure that your code is thoroughly tested in order to uncover any unexpected issues. A simplified version of such a class might look like this:
<?php

class Chapter {

  private $_file;
  private $_title;

  ...

  public function setTitle()
  {

    $pattern = "/<title>(.*?)<\/title>/";
    preg_match($pattern, $this->_file, $matches);

    $this->_title = $matches[1];

  }

?>
To test the Chapter class' setTitle() method, you should make sure that the string found between the <title> tags matches your expectation. You do this by making an assertion within an aptly-named class that extends PHPUnit's PHPUnit_Framework_TestCase class:
<?php

include "../src/Chapter.php";

class ChapterTest extends PHPUnit_Framework_TestCase
{

    protected $_chapter = null;

    public function testTitleMatchesWhenOneTitleInstanceFoundInString()
    {
        
        $docbook = "<docbook><title>Physics 101</title></docbook>";
        $this->_chapter = new Chapter();
        $this->_chapter->setFile($docbook);
        $this->_chapter->setTitle();
        $this->assertEquals($this->_chapter->getTitle(), "Physics 101");

    }

}

?>
There are several important matters to note regarding this example:
If the assertion passes, then so will the test. Otherwise it will fail. We can verify the test outcome by navigating to the test's folder and executing the following command:
%>phpunit ChapterTest.php
PHPUnit 3.4.12 by Sebastian Bergmann.

.

Time: 0 seconds, Memory: 3.50Mb

OK (1 test, 1 assertion)
That dot signifies passage of a test. As your test class expands to include other methods, you'll strive to string those dots together. If a test fails, an F will appear in place of the dot. For instance, if you change the asserted title Physics 101 to Math 254 and run the test again, you'll be greeted with the following output:
PHPUnit 3.4.12 by Sebastian Bergmann.

F

Time: 0 seconds, Memory: 3.50Mb

There was 1 failure:

1) ChapterTest::testTitleMatchesWhenOneTitleInstanceFoundInString
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-Physics 101
+Math 254

/home/wjgilmore/phpunit/code/tests/ChapterTest.php:17

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

Using Data Providers

While it's possible to create a large number of methods, with each intended to test a different title variation, a more efficient approach might involve using a PHPUnit data provider, which allows you to supply an abundance of test data to a single method. For instance, I've placed the following data into a file named titles.txt, with each line consisting of a sample Docbook string followed by a confirmation of the expected parsed title.
<title>Hidden Hawaii</title>||||Hidden Hawaii
<title>Gordon's Great Dilemma</title>||||Gordon's Great Dilemma
<title>My title is Physics 101</title>||||My title is Physics 101
Notice how each line introduces a subtle string variation, the first being a "typical" title, the second including a single quote, and the third using the term "title" in the title.
In the test, I'll configure a data provider method named loadTitlesProvider(), which loads each line of the titles.txt file and splits it according to my designated delimiter (||||):
public function loadTitlesProvider()
{
    $data = array();
    foreach (file('titles.txt') as $line) {
        $data[] = explode("||||", trim($line));

    }

    return $data;
}
Next we'll use the @dataProvider annotation to tell the test where the loaded data will be coming from. Because the $data array consists of two array elements, we're telling the test that two input parameters will be passed, one for each element:
/**
 *
 * @dataProvider loadTitlesProvider
 */
public function testParseTitles($docbook, $title)
{
    $this->_chapter->setFile($docbook);
    $this->_chapter->setTitle();
    $this->assertEquals($this->_chapter->getTitle(), $title);
}
Running this test will produce an output consisting of four dots, just what we're hoping for!

Conclusion

This was but a mere introduction to PHPUnit's powerful testing facility, but hopefully it helps you get past the initial learning curve. Forthcoming issues will build upon what you've learned here, so stay tuned!

About the Author

Jason Gilmore is the founder of EasyPHPWebsites.com and the author of several popular books, including "Easy PHP Web sites with the Zend Framework" and "Beginning PHP and MySQL: From Novice to Professional" (currently in its third edition). Check out his new DZone reference card, titled "Getting Started with the Zend Framework."