Posts tagged phpunit


PHPUnit – You must not expect the generic exception class


While working on updating my unit tests from PHPUnit v3.2 to v3.6, I came across the error message; “You must not expect the generic exception class”, upon first glance it sort of made sense, but after some thought and investigation, it really doesn’t make much sense. My preference is to throw exceptions, and codes, versus throwing specific exceptions, and the code which threw the error was doing just that, throwing a generic exception with an exception code. I spoke with the PHPUnit developer via github, and he stated that a fix is in 3.7 but will not added in 3.6 (current stable). Well I can’t wait for 3.7 to be released so I came up with the following solution:

 * @expectedException Test_Exception
 public function testDivByZero()
     try {
         // Fyi you don't need to do an assert test here, as we are only testing the exception, so just make the call
         $result = $this->object->div(1,0);
     } catch (Exception $e) {
         if ('Exception' === get_class($e)) {
             throw new Test_Exception($e->getMessage(), $e->getCode());

// Test_Exception.php
class Test_Exception extends Exception
    public function __construct($message = null, $code = 0, Exception $previous = null)
        parent::__construct($message, $code, $previous);

Basically all I did was create my own exception class, then when testing if an api call throws an exception, I would check the class of the exception, and if it was a ‘generic’ (Exception) class, then I would wrap it within the custom, expected Test_Exception.


PHPUnit – Unit Tests – Logically Organize Fixtures


I have been working on a project to update an out-of-date Continuous Integration (CI) environment, and one of the tasks was to update the unit tests which required database access. My goal was to ensure that fixtures would be accessible from a central, logical location, much like fundamental coding practices (Don’t Repeat Yourself). After some source code investigation, I found that PHPUnit provides the interface to add multiple fixture files as part of the “getDataset” method for running your unit tests which require database access. Based on this available functionality, I opted to put fixtures together that were not specific to any test, but generic for any test to use them. If you think about it, this really makes the most sense, otherwise you are having to maintain several fixture files which are tightly coupled to specific tests, which are bound to contain data overlap. Even if you do require fixture data which is coupled to a specific to a test, you can still add it to the centralized fixtures, as the other tests won’t even consider the data during their tests, unless you make them aware of the test specific data.

With all that being said I ended up organizing my fixtures like this:

# Template



# Actual




As you can see, I can group my fixture files by database, using the table name for the name of the fixture file. Sure these may be susceptible to change, but only as often as you actually rename databases/tables, so it should be infrequent. Now for some sample content:

# book.yml


  id: 1

  name: War and Peace

  publish_year: 1869

# author.yml


  id: 1

  name_first: Leo

  name_last: Tolstoy



  id: 1

  book_id: 1

  author_id: 1

All three of the above fixture files are organized in the fixture directory under the ‘ml_book’ database and each have a representative row, including the linking table, which will satisfy any FK constraints at the database layer.

The last step is to have your test load the necessary fixtures:

class BookTest extends PHPUnit_Extensions_Database_TestCase

    // Dataset is a required method as defined by parent class
    protected function getDataset()

        // Order is important, as we must load in primary fixtures before attempting to load FK fixtures
        $dataset = new PHPUnit_Extensions_Database_DataSet_YamlDataSet('etc/fixture/ml_book/book.yml');



        return $dataset;

And there you have it, a way to logically group your fixtures and add them to any test in which you need database datasets. I did take a look at the xml file dataset parser, and it DOES NOT afford the same functionality, and to be honest, doesn’t bother me, as I have always felt that yaml is better than xml for configuration files, as the xml files require a lot more text to accomplish the same functionality.

Also, I did some tailing of the query log, and for every table you added in the manner described above, the table would be truncated for every test, ensuring a truly sanitized environment before executing the next test.


PHPUnit – Constant Already Defined – –process-isolation


Just ran across an issue where my PHP unit tests were throwing several “Constant … already defined” errors and couldn’t figure out why. When upgrading the unit tests I had no problem, it was only when I was trying to integrate into CruiseControl that this was happening. Well after some time, I finally figured out the issue was the “ant” command to execute the unit tests was passing the –process-isolation flag to phpunit. Apparently this flag causes everything to be called twice, including the bootstrap file, so if you don’t wrap your “define(CONST, ‘value’)” definitions with an “(!is_defined)” check, you will get the “Constant … already defined” errors.

The simple fix? To simply remove the –process-isolation flag from the command line call.


PHPUnit – Upgrade – Convert assertType to assertInternalType


We recently upgraded phpunit from a very old version to the current 3.6.x version (at time of writing). During the upgrade I noticed that assertType is no longer supported in many of our tests which were testing if something was a string, an array, or an object. So I had to write a quick script to update assertType to assertInternalType and figured I would post it for others if they needed to do the same.

$testsPath = '/path/to/your/tests';

$iter = new RecursiveDirectoryIterator($testsPath, FilesystemIterator::NEW_CURRENT_AND_KEY | FilesystemIterator::SKIP_DOTS);

foreach (new RecursiveIteratorIterator($iter) as $file) {

    $extension = pathinfo($file->getFilename(), PATHINFO_EXTENSION);

    // Only want to deal with php scripts
    if ($extension !== 'php') {

        echo sprintf("Skipped: %s\n", $file->getRealPath());


    echo sprintf("Parsing: %s\n", $file->getRealPath());

    $contents = file($file->getRealPath());

    foreach ($contents as &$content) {
        if ((stripos($content, 'assertType') !== false) &&
            ((stripos($content, 'string') !== false) || (stripos($content, 'array') !== false)) || (stripos($content, 'float') !== false) || (stripos($content, 'object') !== false)) {
            $content = str_ireplace('assertType', 'assertInternalType', $content);

    file_put_contents($file->getRealPath(), $contents, LOCK_EX);


PHPUnit – How to Run PHPUnit Against a Specific Test


The other day I was debugging an error in one of my unit tests, and found it hard to track down because when I ran PHPUnit, it ran all the tests contained in the file where my problem unit test was located. After some Googling and reading the PHPUnit Api Docs, I found that you can specify a test, among other tests, by adding a comment with the @group annotation. Using @group and any group name you wish, you can tell PHPUnit, from the command line, to test only tests belonging to a specific group.

Consider the following:

public function testArrayCount()
    $this->assertCount(2, array('foo', 'bar');

 * @group grain
public function testArrayPopulated()

Notice how I specified the testArrayPopulated() method with a @group grain annotation, now I can tell PHPUnit to only test tests belonging to the grain group.

./phpunit --colors --group grain path/to/your/tests/

Now, when PHPUnit runs, it will only run tests against those tests to which you have assigned the grain group. This @group annotation is a really cool feature of PHPUnit and helped me a lot with debugging my unit tests.


Per Edo’s comments: You can also filter tests by adding ‘–filter testYourTestName’ (two hypens). This will make it so only that test or any test matching the string will be run, same benefits as group, but easier to implement. It does require you to put some thought into how you name the methods within your test.

Per Patrick’s comment: I corrected the order for the command line arguments. The options should ALWAYS go before the path to your tests.

Thanks for the feedback.


PHP – PHPUnit – Use PHPUnit Without PEAR



PHPUnit is a great tool to protect us developers from introducing new defects when adding new features or re-factoring code. However there is one HUGE downside to PHPUnit; it must be installed using PEAR. Personally, I don’t like ‘auto-installers’, I’d prefer to know what exactly is happening behind the scenes with regards to which libraries are required and how they are being called. So when I needed to use PHPUnit on a recent project I shed a tear thinking I would have to break down and install using PEAR.

PHPUnit is not a mythical creature, it doesn’t have magical powers, and as such, it should not intimidate us. It is PHP code, plain and simple, and like any other PHP API Libraries it can be interwoven into our application. So after breaking down the PHPUnit source code, I realized it could be installed without going through PEAR, and without too much headache.

I wrote this article with the goal that it may help others, and maybe even make it’s way to the lead developer of PHPUnit, where he may start using a better autoloading strategy. However, I must warn you to not hold me responsible for any “issues” that may arise on your system by following this article, as it’s strictly demonstrative at this point. There may come a time where I add this code to a GIT repo and officially support it, but not at this point. If you are ok with that, then read on.

Also, note that you can change any of the following guidelines to suit your specific needs. What I am outlining here worked for me, but may not work for you, so feel free to change what you need to, in order to accomplish your end game.

Base Directories

To make things work, we need a base directories from which to work. As with any setting throughout this article, you can change to meet your needs.

Test directory

This directory will be where we put our actual unit tests:


Vendor directory

This directory will be the location where we download and extract PHPUnit source code:


Source Code:

Now that we have our directories in place, lets get PHPUnit source code. Normally you would use PEAR to download, extract, and prepare the source code, but personally I don’t like things of this nature being done for me, I am a big boy, I can handle it myself. So I download each of the core packages manually, then extract them, and set their correct directories in preparation for the next ‘Symlinks‘ step.

The PHPUnit developer uses Github as their version control repo, which is good, but sucks when trying to download packages, as the actual files are abstracted by an intermediary PHP script. What I ended up having to do was download to my local machine, then secure copy them over to the server. Once you have the source files on the server, run the following steps:

$ -> cd ~/projects/vendor

$ -> mkdir phpunit

$ -> cd phpunit

$ -> cp ~/ .

$ -> unzip

# The unzip will result in a weird hash, so I just rename it to
# the correct version based on the original file name
$ -> mv sebastianbergmann-phpunit-f5e159b/ 3.6.7-9

# Don't need source file anymore
$ -> rm *.zip

# Now, we have phpunit locked into a version which we can quickly
# glean when we inspect symlinks to this library
# Lets get the other necessary packages
$ -> mkdir lib

$ -> cd lib
$ -> pwd

# Setup base dirs for phpunit add-ons
$ -> mkdir codeCoverage fileIterator timer

# Now lets copy our add-ons into their respective dirs
$ -> cp ~/ codeCoverage
$ -> cp ~/ timer

# File iterator lib allows you to set a root directory, and phpunit will traverse the directory looking for unit tests
$ -> cp ~/ fileIterator

# Now that we have the files in our lib directory, lets get them setup
$ -> cd codeCoverage
$ -> pwd

$ -> unzip
$ -> mv sebastianbergmann-php-code-coverage-dc2a15a/ 1.1.1-14
$ -> rm *.zip

$ -> cd ../fileIterator
$ -> pwd

$ -> unzip
$ -> mv sebastianbergmann-php-file-iterator-bbaab46/ 1.3.1-1
$ -> rm *.zip

$ -> cd ../timer
$ -> pwd

$ -> unzip
$ -> mv sebastianbergmann-php-timer-b352e92/ 1.0.2-5
$ -> rm *.zip

Ok, now you should have phpunit and it’s core libraries “installed” on your server. In this context, installed is a loose term, as the code isn’t really installed, it’s now available to be hooked into from your testing environment.


As with any 3rd party APIs introduced into your application, it is always best to abstract away version numbers, so you don’t force your application to require files with version numbers in a file’s uri. For example:

// Good
require_once 'path/to/ThirdParty_Vendor/Api/Class.php';

// Bad
require_once 'path/to/ThirdParty_Vendor-1.1.1-9/Api/Class.php';

Why does this matter? Because, when a new version of the file is released, and you upgrade, you won’t have to update all the code references. Instead, just change the related symlink and your application will work as before, except with the newer version of the file.

So lets make the PHPUnit libraries available to our testing environment:

$ -> cd ~/projects/core/test
$ -> mkdir lib
$ -> cd lib
$ -> pwd

$ -> ln -s ~/projects/vendor/phpunit/3.6.7-9/PHPUnit
$ -> ln -s ~/projects/vendor/phpunit/lib/codeCoverage/1.1.1-14/PHP PHPCodeCoverage
$ -> ln -s ~/projects/vendor/phpunit/lib/fileIterator/1.3.1-1/File PHPFileIterator
$ -> ln -s ~/projects/vendor/phpunit/lib/timer/1.0.2-5/PHP PHPTimer

Ok, now we have hooks to phpunit libraries within our testing directory, onto the next step.


A bootstrapper is meant to prepare a library for usage, and that’s exactly what we are going to do. This bootstrapper will setup include_paths along with a few other settings so we can use run our tests correctly. The code is posted here, otherwise it’s too hard to read in wordpress.


Here’s where the magic lies. This autoloader will know how to map files that PHPUnit is requiring, to their symlinked location. It’s pretty easy to follow, all we do is check for a namespace footprint (PHP_Timer), and if it exists, re-map it to our symlink (PHPTimer). The code is posted here, otherwise it’s too hard to read in wordpress.

Changes to PHPUnit Source code

Now for the ugly. It is NEVER a good idea to edit 3rd party (vendor) code directly, otherwise you update and forget about the changes and your app goes to hell. However in this instance I had no choice, and fortunately I was able to limit the change to just one location in the PHPUnit source code. It is a trivial change, but you should add a README to your ~/projects/vendor/phpunit directory to remind yourself to make this change for future upgrades (assuming the lead developer doesn’t change it himself).

My README file:

When upgrading phpunit, 1 change must be made to ensure unit tests work

Why:    This allows us to use our own autloader
File:   PHPUnit/Util/GlobalState.php
Line:   98
    From:    protected static $phpunitFiles;
    To:      public static $phpunitFiles;

This change makes it so we can override the singleton $phpunitfiles. If we don’t over-ride it, then PHPUnit will attempt to use it’s built-in autoloader, which doesn’t work with our setup. By setting the scope from protected to public, we can over-ride the value with an empty array, as the conditional used in source code check is ‘ === NULL’.

phpunit executable

Now we need to create the phpunit executable which will kick off the unit testing. When I was going through the PHPUnit source code, I noticed that the PEAR installer was just renaming the phpunit.php to phpunit. So, lets copy the phpunit executable which came with PHPUnit to our test directory and make a few minor changes:

$ -> pwd

$ -> cp ~/projects/vendor/phpunit/3.6.7-9/phpunit.php .

Now, make the following changes:

#!/usr/bin/env php

// Bring in our bootstrap file
require_once substr(__FILE__, 0, strpos(__FILE__, '/test')) . '/test/Bootstrap.php';

// Set our main define
define('PHPUnit_MAIN_METHOD', 'PHPUnit_TextUI_Command::main');

// Remember we set the scope of $phpunitfiles to public?
// Now we can set it to whatever we want, which is just an empty
// array, which allows our autoloader to handle loading files
PHPUnit_Util_GlobalState::$phpunitFiles = array();

// Kick this pig

Home Stretch

Finally, we made it. Now, we can call on the phpunit executable and run tests. First lets create a sample test:

$ -> pwd

$ -> touch CoreTest/ArrayTest.php

Now lets add an easy test:

class CoreTest_Api_Array_PackageTest extends PHPUnit_Framework_TestCase{
     public function testCount()
         $this->assertCount(2, array('foo', 'bar'));

Now, run the test:

$ -> pwd

$ -> ./phpunit/CoreTest/

Now your ArrayTest test should run (and pass). Notice that we passed a directory to the ./phpunit executable, you can pass a directory, or a specific test to meet your needs. The PHPFileIterator we setup will parse directories for any files ending in *Test.


Hopefully this article wasn’t too hard to follow, and your unit tests are running though PHPUnit, as if you installed through PEAR. If you wouldn’t mind taking the time to contact the lead developer, and let him know that he should drop PEAR and run an autoloader/bootstrap combo like many other PHP libraries/frameworks, I would greatly appreciate it. He has done a good job, but we need to make PHPUnit easier to install and set-up so others don’t get discouraged and give up unit tests altogether.

Go to Top