Tag Archives: Plugin Development

Running Codeception WebDriver Tests For WordPress Plugins on Travis CI

Recently I’ve been exploring creating acceptance tests for my WordPress plugins. I decided that Codeception was the best tool for the job, and WP Browser was a good bootstrap for running WordPress-specific tests. That makes it fairly simple to run WebDriver tests locally using PhantomJS or even a real browser. I also wanted to run my acceptance tests on Travis CI though, and that proved to be a real challenge. After a lot of trial and error I finally got it to work. But rather than trying to tell you all about it, it is much easier just to show you. So I’ve created a demo GitHub repo just for that purpose. Head on over there to check it out and see it in action!

PHPUnit and the WordPress file system API

If you unit test your WordPress projects with PHPUnit, sooner or later you’ll want to test some code that interacts with the filesystem. If you are interacting with the filesystem properly, you’ll be using the $wp_filesystem object.

A few months ago I found myself needing to test some code that created a file using the WordPress filesystem API. I searched for a good solution, and found the information about mocking the filesystem on the PHPUnit website. But after tinkering with vfsStream, I decided it would be easier to build a simple filesystem mocker myself than to integrate vfsStream with the WP Filesystem API. So I did.

The result is the WP Filesystem Mock.

[It] Provides a class that can be used as a mock filesystem, and also a shim for the WordPress filesystem API that uses it. This is useful in unit tests that include simple filesystem operations.

Enjoy!

Creating Your Own PHPUnit @requires Annotations

PHPUnit offers a feature that lets you skip a test when certain requirements aren’t met. This can be done in two ways:

  1. You can manually check if the requirements are met, and then skip the test with $this->markTestSkipped() if they are not.
  2. In some cases, you can use the @requires annotation, and the test will be skipped automatically when the requirements aren’t met.

Using the @requires annotation is nicer, but PHPUnit only has so many options built in. Sometimes you have custom requirements that can’t really be checked reliably with any of the built-in options. An example is when you need some tests you’ve written for a WordPress plugin to run only when WordPress’s multisite feature is enabled on the test site. In my tests, I find myself needing this a lot. So I’ve been writing this over and over:

if ( ! is_multisite() ) {
     $this->markTestSkipped( 'Multisite must be enabled.' );
}

But just yesterday I realized that this was silly, and that I could easily add my own custom @requires annotation. So I did. Here is the code:

	protected function checkRequirements() {

		parent::checkRequirements();

		$annotations = $this->getAnnotations();

		foreach ( array( 'class', 'method' ) as $depth ) {

			if ( empty( $annotations[ $depth ]['requires'] ) ) {
				continue;
			}

			$requires = array_flip( $annotations[ $depth ]['requires'] );

			if ( isset( $requires['WordPress multisite'] ) && ! is_multisite() ) {
				$this->markTestSkipped( 'Multisite must be enabled.' );
			} elseif ( isset( $requires['WordPress !multisite'] ) && is_multisite() ) {
				$this->markTestSkipped( 'Multisite must not be enabled.' );
			}
		}
	}

You just need to add that method to your base test case class, and you will then be able to use @requires WordPress multisite instead of messing with markTestSkipped() all the time. For tests that should only run when multisite isn’t enabled, you can use @requires WordPress !multisite.

You could easily add more options for any other requirements your tests commonly have.

Travis CI, Composer, and PHP 5.2

Once I’ve written some PHP unit tests for my plugins, I like to make sure I put them to good use. I develop the plugins on GitHub, so with the right tools, it’s easy to set up Travis CI to run my tests. This will let me run the tests against all of the PHP versions I need too without the hassle of trying to do this locally.

The only problem is that WordPress still supports PHP 5.2, and while I want to run my tests against that version, I’m using composer to install some of my dev dependencies. And as you probably know, composer requires PHP 5.3. So I searched around the internet to see if anyone had a solution to this dilemma. I did find one project on GitHub, but it requires you to have a separate config file for PHP 5.2, and doesn’t appear to be maintained at this time.

What I was really hoping for was a way to run composer using PHP 5.3 even when the tests are running on 5.2, since all of the PHP versions are installed on the Travis test box. I couldn’t find any helpful information about switching PHP versions on Travis, but with a little research into phpenv (which Travis uses to manage the PHP environment), I was able to figure something out.

It’s actually as easy as this:

phpenv global 5.3
composer install
phpenv global "$TRAVIS_PHP_VERSION"

Just drop that into the before_install section of your .travis.yml, and you’re ready to go!

WordPress Unit Testing with WP_Http

If you use wp_remote_request() or other wrappers for WP_Http methods in your code, this makes it difficult to test, especially if the remote server may not be reachable from your testing environment. That’s why I created the WP_HTTP_UnitTestCase to solve this by letting you mock the remote responses.

The usage details are there in the repository’s readme file.

It lets you mock the remote responses coming from the server, and also captures the data that was sent to the remote server so you can check that the correct requests are made.

As I continue to write unit tests for WordPress plugins I create, I think I’ll find this helper useful. I hope you might as well.