Unit Testing in WordPress

Unit testing in PHP is one of those things that people talk about but can be difficult to get your head around until you take the leap and actually write your first test.

It can also be difficult to see the value in taking the time to write tests if you’ve never done it before, but take my word for it – it’s one of those things that when you start writing tests you’ll wonder why the hell it took you so long to start writing tests and how you ever managed before!

I can pretty much guarantee you it will make you change the way you structure your code too, in my case very much for the better.

Getting started

First you’ll need to install PHPUnit.

composer global require phpunit/phpunit

The easiest way to add tests to a plugin is to use WP-CLI.

wp scaffold plugin-tests {plugin-name}

Check out the documentation for more details about this command.

When you’ve run the command, cd to your plugin directory and run.

./bin/install-wp-tests.sh {db-name} {db-user} {db-pass} [db-host] [wp-version] [skip-database-creation]

Just run something like the following:

./bin/install-wp-tests.sh wordrpress_tests mysql_username mysql_password

To install the test library and the tests database. Do not use a real database for this as it will be deleted when you run your tests!!

Writing your tests

Alright, you’ve made it this far! You’ll notice a couple of files added to your plugin now. Check out the default tests class at: tests/tests-sample.php. It should look like this:

/**
 * Sample test case.
 */
class SampleTest extends WP_UnitTestCase {

    /**
     * A single example test.
     */
    function test_sample() {
        $this->assertTrue( true );
    }
}

If you run

phpunit

from your plugin directory you should see something like the following:

Unit tests result

Awesome brah!! Now you just need to write some actual tests. Sitepoint has a pretty good introduction article about this. I suggest just playing around with the API it feels natural.

Try adding the following to your tests class and see what happens :)

function test_something() {
    $string = 'Nice :)';
    $this->assertEquals( 'Nice :)', $string );
}

function test_something_that_fails() {
    $string = 'Nice :)';
    $this->assertEquals( 'BAD :(', $string );
}

There’s a bunch of assertions you can use depending on your use case. They’re all detailed on the PHPUnit site.

Happy testing!

Update! I’ve since written a sort of part 2 to this post that goes a bit deeper into how to integrate your tests with WordPress and even other plugins. Check it out, if you fancy diving a wee bit deeper into the subject.

Add a category to media items in WordPress

If you want to add categories to images and/or other uploaded files in your WordPress media library (in versions 3.5 and above) it’s really easy — once you know how. First register the taxonomy (I’m just using the built in ‘category’ taxonomy type in WordPress, but you could be all fancy and add your own taxonomy if you really want to).

/** Register taxonomy for images */
function olab_register_taxonomy_for_images() {
    register_taxonomy_for_object_type( 'category', 'attachment' );
}
add_action( 'init', 'olab_register_taxonomy_for_images' );

Now add the category field to the Media Library table. This will also add a filter to the table to allow search of attachments by category. Super useful if you’ve got a bunch of files you need to categorize.

 /** Add a category filter to images */
function olab_add_image_category_filter() {
    $screen = get_current_screen();
    if ( 'upload' == $screen->id ) {
        $dropdown_options = array( 'show_option_all' => __( 'View all categories', 'olab' ), 'hide_empty' => false, 'hierarchical' => true, 'orderby' => 'name', );
        wp_dropdown_categories( $dropdown_options );
    }
}
add_action( 'restrict_manage_posts', 'olab_add_image_category_filter' );

Make sure to replace ‘olab’ with whatever prefix you’re using in your theme and/or plugin.

WordPress: create a widget using code from a plugin class

I’m writing a new WordPress plugin: an audio player written atop the marvellous jPlayer. I wanted to give the user the option to add the audio player via a widget, but as my plugin was written OOP I wasn’t really sure how to register the widget using code from my plugin.

It turns out it wasn’t particularly difficult, but I couldn’t find any documentation about it online, so I figured I’d write this wee post, in the hope that it might come in useful for my fellow WordPressers!

My plugin code is written in OOP:

class MyCoolPlugin {
// All my methods + properties here
}
// Instantiate the class
$cool_plugin = new MyCoolPlugin();

The class contains a method to create the HTML that I want to use for both a shortcode and a widget.

class MyCoolPlugin {
  // Returns the HTML for a shortcode or widget
  function shortcode_widget() {
    return '<p>HTML rocks</p>';
  }
}
// Instantiate the class
$cool_plugin = new MyCoolPlugin();

Register my widget:

class CoolWidget extends WP_Widget {
  function CoolWidget() {
    // Instantiate the parent object
    parent::__construct( false, 'Cool Widget' );
  }
}

Then I can add the HTML from the shorcode_widget method of MyCoolClass like so:

class CoolWidget extends WP_Widget {
  function CoolWidget() {
    // Instantiate the parent object
    parent::__construct( false, 'Cool Widget' );
  }
  function widget($args, $instance) {
    // reuse my plugin's code
    global $cool_plugin;
    echo $cool_plugin->shortcode_widget();
  }
}

Nice. Saves me writing a bunch of code multiple times, which I guess is the main point of OOP!

How to split your WordPress posts into two columns

The other day, whilst merrily making a website for an ensemble called Tesserae, I needed to figure out how to display my posts in 2 columns, side by side. In this case, the posts were a custom post type biographies that I used to display the various members biographies on the site.

It wasn’t hard to do, here’s the code I used to display half of the posts:

<?php // Get the number of posts in the custom post type 'biographies'
$count = wp_count_posts( 'biographies' ); ?>

Let’s say the total number of posts is 7.

<?php // Divide the number of published posts by 2 and round up in case we get a fraction
$num_biogs = ceil( $count->publish / 2 ); ?>

This would give us 4. We must round up this number otherwise, we’d get 3.5 and that’s no good!

<?php // Now use this number for the showposts parameter in our query
$biogs = new WP_Query( 'post_type=biographies&showposts=' . $num_biogs );
while ( $biogs->have_posts() ) : $biogs->the_post();
// the_title(); the_content(); etc
endwhile; wp_reset_query(); ?>

And the remaining posts:

<?php // Now use the variable $num_biogs as the offset parameter in another query
$biogs = new WP_Query( 'post_type=biographies&showposts=-1&offset=' . $num_biogs );
while ( $biogs->have_posts() ) : $biogs->the_post();
// the_title(); the_content(); etc
endwhile; wp_reset_query(); ?>

Obviously this is only the PHP, and you’re going to need some HTML there to actually use this! I just floated a couple of <div>s side by side, then popped the first block of code inside the left-hand <div> and the 2nd chunk in the 2nd <div>.

You can see the finished product at http://tesserae-la.com/who/