Just hearing unit tests makes even some of the most seasoned programmers shudder. Unit testing can be such a controversial topic that some veteran programmers have heard of them but know nothing more than what they hear in the wild ranging from “testing isn’t a programmer’s job”, to “writing tests is too time consuming to be worthwhile,” to my favorite “I write code that doesn’t need to be tested.” As you will hopefully learn, these excuses are not only silly, they are the antithesis of what unit tests are about.
While it may seem like a whole blog post dedicated to setting up unit tests is complicated, you’ll see that in the end, when you have WP-CLI installed, it’s really just a few keystrokes to get going.
What is Unit Testing and Why Unit Test?
Thinking about how to define what a unit test is exactly, I took the a basic approach and checked out what Wikipedia says about them:
In computer programming, unit testing is a software testing method by which individual units of source code, sets of one or more computer program modules together with associated control data, usage procedures, and operating procedures are tested to determine if they are fit for use.
That’s a bit of a mouthful. I think it could be better rewritten as
Unit testing is code that runs pieces of code (i.e., functions, methods) passing specific data and ensuring the expected outcome.
Code that makes sure your code works as expected.
Back to those excuses about why we don’t write unit tests. While excuses are prevalent, they are unfounded (for the most part). I agree, getting in the habit of writing (more) testable code and writing tests is time consuming, but doing so can save an exponential amount of headaches. Simply put, unit testing can help you feel confident changing existing code or introducing new components and not staying up at night anxious about impending bug ticket blitzes about cascading and unexpected side-effects.
Getting Started With WordPress Unit Testing
Since the target audience for this article is for WordPress users let’s take a look at how to get started writing tests for a plugin. The only dependencies, outside of WordPress and code to be tested, to get started, are WP-CLI, Subversion and PHPUnit installed on your development environment.
For this demo I have put together a pretty simple Vagrant script with two shell scripts to get you up and running with a development environment. This requires you to have VirtualBox, Vagrant and the Vagrant DNS plugin installed.
- To install Vagrant DNS, after installing Vagrant, run from the shell
vagrant plugin install vagrant-dns.
- After all that is installed, clone the repo (i.e. git clone https://github.com/voceconnect/unit-testing-demo).
- CD into unit-testing-demo and run
vagrant upand let vagrant do it’s magic.
- Once done navigate to http://unittestdemo.dev/ and you should have a fully functioning WordPress installation. The wp-admin user/password is user/password, the database user/password is root/root.
The plugin we are going to write tests for will be in the directory /vagrant/wp-content/plugins/demo-plugin/ on the VirtualBox and this directory syncs with [directory you cloned the repo into]/wp-content/plugins/demo-plugin/.
WP-CLI has a very simple to set up testing scaffold. The syntax is
wp scaffold plugin-tests PLUGIN-DIRECTORY-NAME from the root directory of the site. Since WP-CLI is set up on our virtual machine, let’s ssh into it and set up our scaffold:
- From the same directory you ran vagrant up, run
vagrant ssh. This will bring you into the virtual machine.
- CD into /vagrant
- Set up the testing scaffold by executing
wp scaffold plugin-tests demo-plugin. This should return Success: Created test files.
- If you CD into wp-content/plugins/demo-plugin and list out the contents (ls) there should be new files (.travis.yml and phpunit.xml) and new directories (tests and bin).
- We need to set up a testing instance of WordPress for our testing suite, which the scaffold provided us a script for, execute:
bash bin/install-wp-tests.sh test-db root root localhost latestfrom within /vagrant/wp-content/plugins/demo-plugin. This creates a table “demo_plugin_tests” using the username/password root/root within localhost using the latest version of WordPress.
Our test suite is installed! We can make sure by running
phpunit from /demo-plugin and we should see something similar to the following:
The reason it says 1 test (and because it’s green means the test passed) is that the scaffold sets up a dummy test that checks if the value of true is true, which shockingly is true (more to come on that when we go over assertions).
One last minor tweak to the files that the WP-CLI scaffolding created. Open up phpunit.xml in the plugin directory and add the following after the closing of the <testsuites> element. The phpunit.xml should look similar to below:
<phpunit bootstrap="tests/bootstrap.php" backupGlobals="false" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" > <testsuites> <testsuite> <directory prefix="test-" suffix=".php">./tests/</directory> </testsuite> </testsuites> <filter> <whitelist processUncoveredFilesFromWhitelist="true"> <directory suffix=".php">.</directory> <exclude> <directory suffix=".php">./tests</directory> </exclude> </whitelist> </filter> </phpunit>
This tells PHPUnit to only look in the files in the current directory and below and ignore the tests directory – which greatly decreases the time it takes to run coverage reports.
As mentioned earlier, getting to this point may seem like it took a while, but the process is pretty straight forward thanks to the WP-CLI scripts. At this point we are ready to take the next steps on this journey towards creating a plugin and writing a set of tests that cover its functionality.