PHP
  Home arrow PHP arrow Unit Testing in Detail
Dev Shed Forums 
Administration  
AJAX  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Forums Sitemap 
IBM® developerWorks 
Sun Developer Network 
Dedicated Servers 
E-Commerce Hosting 
Linux Web Hosting 
Managed Hosting 
Small Business Hosting 
Moblin 
JMSL Numerical Library 
VPS Hosting 
Weekly Newsletter

 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
PHP

Unit Testing in Detail
By: Sams Publishing
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 2
    2006-10-26

    Table of Contents:
  • Unit Testing in Detail
  • Additional Features in PHPUnit
  • Adding More Test Conditions
  • Adding Listeners

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Unit Testing in Detail


    (Page 1 of 4 )

    Last week, we introduced you to setting up a unit testing framework. This week, you will learn about running multiple tests simultaneously, creating more informative error messages, and more. This article, the second of three parts, is excerpted from chapter 6 of the book Advanced PHP Programming, written by George Schlossnagle (Sams; ISBN: 0672325616).

    Separate Test Packaging

    Given the drawbacks to inlining tests, I choose to avoid that strategy and write my tests in their own files. For exterior tests, there are a number of different philosophies. Some people prefer to go the route of creating a t or tests subdirectory in each library directory for depositing test code. (This method has been the standard method for regression testing in Perl and was recently adopted for testing the PHP source build tree.) Others opt to place tests directly alongside their source files. There are organizational benefits to both of these methods, so it is largely a personal choice. To keep our examples clean here, I use the latter approach. For every library.inc file, you need to create a library.phpt file that contains all the PHPUnit_Framework_TestCase objects you define for it.

    In your test script you can use a trick similar to one that you used earlier in this chapter: You can wrap a PHPUnit_Framework_TestSuite creation and run a check to see whether the test code is being executed directly. That way, you can easily run the particular tests in that file (by executing directly) or include them in a larger testing harness.

    EmailAddress.phpt looks like this:

    <?php
    require_once "EmailAddress.inc";
    require_once 'PHPUnit/Framework/TestSuite.php';
    require_once 'PHPUnit/TextUI/TestRunner.php';
    class EmailAddressTestCase extends
    PHPUnit_Framework_TestCase { public function _ _construct($name) { parent::_ _construct($name); } public function testLocalPart() { $email = new EmailAddress("george@omniti.com"); // check that the local part of the address is
    equal to 'george' $this->assertTrue($email->localPart == 'george') ; } public function testDomain() { $email = new EmailAddress("george@omniti.com"); $this->assertTrue($email->domain == 'omniti.com'); } } if(realpath($_SERVER[PHP_SELF]) == _ _FILE_ _) { $suite = new
    PHPUnit_Framework_TestSuite('EmailAddressTestCase'); PHPUnit_TextUI_TestRunner::run($suite); } ?>

    In addition to being able to include tests as part of a larger harness, you can execute EmailAddress.phpt directly, to run just its own tests:

    PHPUnit 1.0.0-dev by Sebastian Bergmann.
    ..
    Time: 0.0028760433197
    OK (2 tests)

    Running Multiple Tests Simultaneously

    As the size of an application grows, refactoring can easily become a nightmare. I have seen million-line code bases where bugs went unaddressed simply because the code was tied to too many critical components to risk breaking. The real problem was not that the code was too pervasively used; rather, it was that there was no reliable way to test the components of the application to determine the impact of any refactoring.

    I'm a lazy guy. I think most developers are also lazy, and this is not necessarily a vice. As easy as it is to write a single regression test, if there is no easy way to test my entire application, I test only the part that is easy. Fortunately, it's easy to bundle a number of distinct TestCase objects into a larger regression test. To run multiple TestCase objects in a single suite, you simply use the addTestSuite() method to add the class to the suite. Here's how you do it:

    <?php
    require_once "EmailAddress.phpt";
    require_once "Text/Word.phpt";
    require_once "PHPUnit/Framework/TestSuite.php";
    require_once "PHPUnit/TextUI/TestRunner.php";
    $suite = new PHPUnit_Framework_TestSuite();
    $suite->addTestSuite('EmailAddressTestCase');
    $suite->addTestSuite('Text/WordTestCase');
    PHPUnit_TextUI_TestRunner::run($suite);
    ?>

    Alternatively, you can take a cue from the autoregistration ability of PHPUnit_Framework_TestSuite to make a fully autoregistering testing harness. Similarly to the naming convention for test methods to be autoloaded, you can require that all autoloadable PHPUnit_Framework_TestCase subclasses have names that end in TestCase. You can then look through the list of declared classes and add all matching classes to the master suite. Here's how this works:

    <?php
    require_once "PHPUnit/FrameWork/TestSuite.php";
    class TestHarness extends
    PHPUnit_Framework_TestSuite { private $seen = array(); public function _ _construct() { $this = parent::_ _construct(); foreach( get_declared_classes() as $class) { $this->seen[$class] = 1; } } public function register($file) { require_once($file); foreach( get_declared_classes() as $class) { if(array_key_exists($class, $this->seen)) { continue; } $this->seen[$class] = 1; // ZE lower-cases class names, so we look for
    "testcase" if(substr($class, -8, 8) == 'testcase') { print "adding $class\n"; $this->addTestSuite($class); } } } } ?>

    To use the TestHarness class, you simply need to register the files that contain the test classes, and if their names end in TestCase, they will be registered and run. In the following example, you write a wrapper that uses TestHarness to autoload all the test cases in EmailAddress.phpt and Text/Word.phpt:

    <?php
    require_once "TestHarness.php";
    require_once "PHPUnit/TextUI/TestRunner.php";
    $suite = new TestHarness();
    $suite->register("EmailAddress.phpt");
    $suite->register("Text/Word.phpt");
    PHPUnit_TextUI_TestRunner::run($suite);
    ?>

    This makes it easy to automatically run all the PHPUnit_Framework_TestCase objects for a project from one central location. This is a blessing when you're refactoring central libraries in an API that could affect a number of disparate parts of the application.

    More PHP Articles
    More By Sams Publishing


       · This article is an excerpt from the book "Advanced PHP Programming," published by...
       · Not bad article if you need to test your PHP *classes* but what about approaches on...
     

    Buy this book now. This article is excerpted from chapter 6 of the book Advanced PHP Programming, written by George Schlossnagle (Sams; ISBN: 0672325616). Check it out today at your favorite bookstore. Buy this book now.

       

    PHP ARTICLES

    - Validating Web Forms with the Code Igniter P...
    - Output Buffering
    - Paginating Database Records with the Code Ig...
    - HTTP Headers in Web Development
    - Project Management: Administration
    - Building a Database-Driven Application with ...
    - User Authentication for a Project Management...
    - Introduction to the CodeIgniter PHP Framework
    - Adding Users for a Project Management Applic...
    - Migrating Class Code for a MIME Email to PHP...
    - Login and Logout Authentication for a Projec...
    - Composing Messages in HTML for MIME Email wi...
    - Project Management: Authentication
    - A Better Way to Determine MIME Types for MIM...
    - Project Management Overview





    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 1 hosted by Hostway