Whether you are currently writing a WordPress plugin and have decided to embrace unit testing or you are about to begin development of a plugin and want to unit test it from the start, learning how to do it correctly is a must.

This guide assumes you have a working LAMP stack (or similar) setup on your development machine and have reasonable knowledge of databases. For easy set up of a LAMP stack see XAMMP (windows/linux) or MAMP (Mac). You should also have Git installed.

Unit Testing Overview

Unit testing is a great way to ensure that everything is working as expected. When refactoring your code base later down the line you’ll be glad you’ve written full and thorough unit tests. The basis of Test Driven Development (TDD) involves:

  1. Write a failing test.
  2. Write code so that the test passes.
  3. Refactor.

Hopefully you’re reasonably familiar with that process. I’m not going into the whole TDD thing here, so read around for more info. However, unit testing a WordPress plugin is a a totally different operation than a standard PHP app.

The Problem With Standard Practices

If you try to go about unit testing your plugin using the standard means that you would with any other app then you are likely going to fail. This is because these methods will not run any of the WordPress core code, therefore if you do anything like get_option() in your plugin that will instantly fail. So how do we go about this without rewriting all of your classes with duplicate methods in order to test? You also want to be testing against a clean WordPress install for every test so that any remains from failed tests will not impact the success of future tests.

Using The WordPress-Tests Library

Some clever bloke has written a fantastic library that handles all of the tests that the WordPress core codebase uses. So we are going to make use of that library in order to test our plugin. What this does is runs all of your plugin’s unit tests within a clean WordPress environment every time you run them. It makes use of the PHPUnit PEAR extension, so it’s built on strong standards that you are (hopefully) familiar with from previous PHP projects.

Getting Set Up

Firstly you need PHPUnit. The easiest way to get hold of this is using PEAR. This can be achieved by running the following commands as root.

pear config-set auto_discover 1
pear install pear.phpunit.de/PHPUnit

Once run, test everything works by running:
phpunit --version

If you are having issues then refer to the PHPUnit Installation Manual.

Now to set up your environment. You’ll need the wordpress-test framework somewhere on your development machine.

mkdir ~/src
cd ~/src
git clone https://github.com/nb/wordpress-tests.git

In the new ~/src/wordpress-tests/ folder you need to rename the unittests-config-sample.php file to unittests-config.php and open it up with your favourite editor. You should set the ABSPATH variable to the path to your development WordPress install and the DB settings to point to a database that should be used for testing. It is recommended to use a separate database for testing, if that isn’t possible then at least use a different $table_prefix.

That’s the testing framework all set up!

Using the Framework in your Plugin’s Tests

Change directories to your plugin directory and create a new file called phpunit.xml. This file is what holds the settings for the PHPUnit command. You will need the following content in that file:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
        backupStaticAttributes="false"
        colors="true"
        convertErrorsToExceptions="true"
        convertNoticesToExceptions="true"
        convertWarningsToExceptions="true"
        processIsolation="false"
        stopOnFailure="false"
        syntaxCheck="false"
        bootstrap="tests/bootstrap.php"
        >
        <testsuites>
                <testsuite name="Plugin Test Suite">
                        <directory>./tests/</directory>
                </testsuite>
        </testsuites>
</phpunit>

Without these settings, the testing framework may misbehave. You can change ‘Plugin Test Suite’ to the name of your plugin.

Now create a new directory in your plugin directory called tests. This is where all your tests will live. In this directory you need to create a new file called bootstrap.php. Every time your tests run this file will be loaded – it is responsible for loading the WordPress-Tests library. This file needs the content:

<?php
// Load the test environment
// https://github.com/nb/wordpress-tests

$path = '/home/ollie/src/wordpress-tests/bootstrap.php';

if (file_exists($path)) {
        $GLOBALS['wp_tests_options'] = array(
                'active_plugins' => array('plugin-name/main-plugin-file.php')
        );
        require_once $path;
} else {
        exit("Couldn't find wordpress-tests/bootstrap.phpn");
}

Obviously you will need to change the $path variable to point to where you cloned the wordpress-tests library and the active-plugins line to reflect the name of the folder that your plugin is saved in and the main file name of the plugin.

Creating the Tests

All the setting up is done, it’s now on to creating your tests. If you have no experience with using PHPUnit then Google around for some tutorials.

In the tests folder create a new file called MyPluginTest.php. Open this up and paste the following template (changing the applicable references to ‘my-plugin’):

<?php
/**
 * MyPlugin Tests
 */
class MyPluginTest extends WP_UnitTestCase {
    public $plugin_slug = 'my-plugin';

    public function setUp() {
        parent::setUp();
        $this->my_plugin = $GLOBALS['my_plugin'];
    }

    public function testTrueStillEqualsTrue() {
        $this->assertTrue(true);
    }
}

All this test will do is check that true is true. Should always pass! Save this and return to your plugin directory and run PHPUnit.

phpunit

You should see that it runs the test and passes! If you get some errors then you’ve probably got a problem with your configuration or directory structure. Try to fix it yourself but if you need any help then feel free to leave a comment and I’ll try to help.

All that’s left to do is follow the TDD paradigm and create some tests. Go have a beer – you’ve done the whole world a favour by unit testing.

This guide was inspired by this question on Stack Overflow. If you are having issues have a look there and see if that post clarifies anything for you. The WordPress Codex page on Automated Testing is also quite good.

Ollie Armstrong Software Developer

Ollie works on WordPress plugins, supporting CatN systems and other projects. Still in college, he might be the youngest Zend certified developer in the UK!