Home arrow PHP arrow Page 4 - Unit Testing

Inline Packaging - PHP

Having a formalized unit testing infrastructure for your projects will save you time in the long run, especially when looking for bugs in code. This article introduces you to setting up a unit testing framework. It is excerpted from chapter 6 of the book Advanced PHP Programming, written by George Schlossnagle (Sams; ISBN: 0672325616).

  1. Unit Testing
  2. An Introduction to Unit Testing
  3. Adding Multiple Tests
  4. Inline Packaging
By: Sams Publishing
Rating: starstarstarstarstar / 6
October 19, 2006

print this article



One possible solution for test packaging is to bundle your tests directly into your libraries. Because you are a tidy programmer, you keep all your functions in subordinate libraries. These libraries are never called directly (that is, you never create the page http://www.omniti.com/EmailAddress.inc). Thus, if you add your testing code so that it is run if and only if the library is called directly, you have a transparent way of bundling your test code directly into the code base.

To the bottom of EmailAddress.inc you can add this block:

if(realpath($_SERVER['PHP_SELF']) == _ _FILE_ _) {
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->assertEquals($email->domain, 'omniti.com'); } } $suite = new
PHPUnit_Framework_TestSuite('EmailAddressTestCase'); PHPUnit_TextUI_TestRunner::run($suite); }

What is happening here? The top of this block checks to see whether you are executing this file directly or as an include. $_SERVER['PHP_SELF'] is an automatic variable that gives the name of the script being executed. realpath($_SERVER[PHP_SELF]) returns the canonical absolute path for that file, and _ _FILE_ _ is a autodefined constant that returns the canonical name of the current file. If _ _FILE_ _ and realpath($_SERVER[PHP_SELF]) are equal, it means that this file was called directly; if they are different, then this file was called as an include. Below that is the standard unit testing code, and then the tests are defined, registered, and run.

Relative, Absolute, and Canonical Pathnames - People often refer to absolute and relative pathnames. A relative pathname is a one that is relative to the current directory, such as foo.php or ../scripts/foo.php. In both of these examples, you need to know the current directory to be able to find the files.

An absolute path is one that is relative to the root directory. For example,  /home/george/scripts/ foo.php is an absolute path, as is  /home/george//src/../scripts/./foo.php. (Both, in fact, point to the same file.)

A canonical path is one that is free of any /../, /./, or //. The function realpath() takes a relative or absolute filename and turns it into a canonical absolute path.  /home/george/scripts/foo.php is an example of a canonical absolute path.

To test the EmailAddress class, you simply execute the include directly:

 (george@maya)[chapter-6]> php EmailAddress.inc 
PHPUnit 1.0.0-dev by Sebastian Bergmann.
Time: 0.003005027771
OK (2 tests)

This particular strategy of embedding testing code directly into the library might look familiar to Python programmers because the Python standard library uses this testing strategy extensively.

Inlining tests has a number of positive benefits:

  • The tests are always with you.

  • Organizational structure is rigidly defined.

It has some drawbacks, as well:

  • The test code might need to be manually separated out of commercial code before it ships.

  • There is no need to change the library to alter testing or vice versa. This keeps revision control on the tests and the code clearly separate.

  • PHP is an interpreted language, so the tests still must be parsed when the script is run, and this can hinder performance. In contrast, in a compiled language such as C++, you can use preprocessor directives such as #ifdef to completely remove the testing code from a library unless it is compiled with a special flag.

  • Embedded tests do not work (easily) for Web pages or for C extensions.

Please check back next week for the continuation of this article.

>>> More PHP Articles          >>> More By Sams Publishing

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort


- Hackers Compromise PHP Sites to Launch Attac...
- Red Hat, Zend Form OpenShift PaaS Alliance
- PHP IDE News
- BCD, Zend Extend PHP Partnership
- PHP FAQ Highlight
- PHP Creator Didn't Set Out to Create a Langu...
- PHP Trends Revealed in Zend Study
- PHP: Best Methods for Running Scheduled Jobs
- PHP Array Functions: array_change_key_case
- PHP array_combine Function
- PHP array_chunk Function
- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...

Developer Shed Affiliates


Dev Shed Tutorial Topics: