Test-Driven PHP Development

Web Languages
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

It's a new way of looking at an old problem.


Editor's note: This article is an excerpt from the new book Advanced Guide to PHP on IBM i.


Have you ever run into a situation where you built something or made a change somewhere only to have it break something else? If your answer is no, wait until you graduate and get a job. It is bound to happen, and sometimes it will happen with catastrophic effects.


Part of the problem is that we do not often test our applications very well. Yes, we press refresh and maybe use a debugger, but do we have a system for testing?


But beyond using a testing system, we must go a little deeper. To best use our testing system, we have to build a testable application. A testable application is generally more complicated than the typical PHP application. However, a testable application pays for itself exponentially because it lets us repeatedly test all parts of our application to verify that they are working properly from start to finish.


Test-driven development is the practice of building out an application based on tests, rather than building it in a fluid manner. The way we naturally build applications is that we have a problem, we figure out how to solve it, we build the application, and then we test it. Test-driven development flips that process around. Instead of initially building out the application, we build the tests first and then write our code to pass the tests. It sounds a little counterintuitive, because all through our schooling years, the last thing we did before going to the graduation party was be tested. However, building our tests at the outset provides a lot of benefits.


First, it forces us to think of how we intend to use the functionality that we are creating. Second, if we are building our tests before building out the application, we are more likely to consider the required range of inputs, making us more likely to test edge conditions. This testing will lead to more stable software. Third, it makes us more productive. Unit testing has been shown both in studies and in real life to make developers more productive overall, and it is one of the few practices that have virtually no downside.


Some might claim that because you must now write both test and actual program code, you are becoming less productive. Although this might seem true at first glance, in practice it is often not the case. When writing unit tests, you are testing individual pieces of functionality. With traditional debugging, you are trying to coax the browser into performing a certain action, whether or not it wants to. And though you might be writing more code, you are writing code that is intended to verify that the function is doing what it is supposed to be doing.


Unit testing can be a complex subject to cover, but even a basic understanding of it can pay for itself. I will explain only the basics of performing unit testing here. For a more in-depth treatment of the subjects, complete books are available that provide a deeper guide into how to do unit testing.




By far, the most popular PHP unit testing software is PHPUnit. It is maintained by Sebastian Bergman, and you can it download at PHPUnit is also included in your copy of Zend Studio.


Generally, tests are created in a separate directory from the application to prevent them from being deployed along with the application. You can, of course, put the test files alongside your class structure and remove any unwanted tests as part of your deployment process. But it is usually easier to disallow a single directory than to hope that your pattern-matching packaging process excludes all your test files.


Your tests’ structure should generally follow the structure of the items you are testing. So say you have a class called My\Class. The files related to it should be as follows:









One practice you can use in some scenarios is to build out your class structure first and stub out the methods that you will be using. Consider this class:


namespace My;


class Address



     public function setState($state)




     public function getState()






This example defines the method that the class will use but does not add any functionality to it. So you can open the PHPUnit test case window in Zend Studio and have Studio create the test class for you (Figure 7.1).


Figure 7.1: Creating a test class in the PHPUnit test case window


Truth be told, Zend Studio creates a relatively ugly file. So let’s clean that file up a little:


use My\Address;


class AddressTest extends PHPUnit_Framework_TestCase {




       * @var Address


     private $Address;


     protected function setUp() {

           parent::setUp ();

           $this->Address = new Address(/* parameters */);



     public function testSetState() {

           // TODO Auto-generated AddressTest->testSetState()

           $this->markTestIncomplete ( "setState test not implemented" );


           $this->Address->setState(/* parameters */);




What is missing in this code? It is require_once calls to the individual class you are testing along with the unit testing code. When I create a new unit test, I remove the require_once calls. I also delete a lot of boilerplate comments and other things. But to load the classes, you must first install an autoloader.


To set this up, you define a bootstrap file. Often, the bootstrap will be a PHP file in the root of the test directory. The PHP file will be called before the test run to set up the environment. One thing you do in that file is bootstrap the tests with an autoloader:




     . PATH_SEPARATOR . realpath( __DIR__ . '/../lib')

     . PATH_SEPARATOR . realpath( __DIR__)



spl_autoload_register(function($class) {

     if (strpos($class, '\\') !== false) {

           $class = str_replace('\\', '/', $class);

     } else if (strpos($class, '_') !== false) {

           $class = str_replace('_', '/', $class);



     $filename = $class . '.php';


     include $filename;



This bootstrap file can contain any functionality required to prepare the system for a test. Here, you needed only an autoloader and to set the include path. But in some cases, you might have to set a database connection or change a web service URL to a debug service.


You still have a problem, though. PHPUnit does not know where the bootstrap is. Luckily, you can configure PHPUnit with this information (and much more). PHPUnit will look for a file called phpunit.xml, which can contain various configuration options to modify how it works. Following is an example phpunit.xml file from the PHPUnit manual:


<phpunit backupGlobals="true"





















<!-- ... -->



For your purposes, you need only one attribute set:






With that, you are ready to go.


Editor's note: To learn more about using PHPUnit in Zend Studio for test-driven development, see Chapter 7 of Advanced Guide to PHP on IBM i.


Kevin Schroeder

Kevin Schroeder has a memory TTL of 10 years, and so he has been working with PHP for longer than he can remember. He is a member of the Zend Certification Advisory Board and is a Magento Certified Developer Plus. He has spoken at numerous conferences, including ZendCon, where he was twice the MC. When his head isn’t in code (if code is poetry, then it is Vogon poetry), Kevin is writing music, having been a guitarist since hair bands were cool (and having survived their welcomed demise). He has recorded two albums, Coronal Loop Safari and Loudness Wars. Kevin’s wisdom is dispensed to his loyal followers on Twitter at @kpschrade and on his blog at, where he speaks in the first person.

MC Press books written by Kevin Schroeder available now on the MC Press Bookstore.

Advanced Guide to PHP on IBM i Advanced Guide to PHP on IBM i
Take your PHP knowledge to the next level with this indispensable guide.
List Price $79.95

Now On Sale

The IBM i Programmer’s Guide to PHP The IBM i Programmer’s Guide to PHP
Get to know the PHP programming language and how it can--and should--be deployed on IBM i.
List Price $79.95

Now On Sale

You Want to Do What with PHP? You Want to Do What with PHP?
This book for the creative and the curious explores what’s possible with PHP.
List Price $49.95

Now On Sale



Support MC Press Online

$0.00 Raised:


   Support MC Press Online

MC Contributors Header 785x150

Support MC Press with a contribution of any size.

Your support helps MC Press deliver free quality information about the new and legacy technologies you rely on to IT Professionals everywhere. Our goal continues to be helping you become more productive on the job and get more out of your career. Every contribution, regardless of size, furthers that goal.