Archives

Make Sure Your Functions Function: Unit Testing

Hopefully you’ve checked out our new contributor guide and you’re ready to submit your first patch — thanks! But before you send your .diff out into the world, run a unit test to make sure everything’s working as it should.

Never written or run a unit test? Here’s a quick get-started and best practices guide.

Why Unit Test?

Moving forward (beyond Jetpack 2.3.4) all new functionality must be accompanied by a successful unit test. Unit tests are small snippets of code that ensure a the new code is working as expected.

Unit testing is a crucial piece of your contribution to Jetpack: it verifies both that Jetpack works as expected, and that the updates won’t break the existing code. As we work together to build new features and zap the bugs, unit tests provide ongoing quality assurance that keep Jetpack strong and reliable.

Set Up a Unit Testing Environment

To run local tests, you’ll need to install PHPUnit and make sure you’ve got a few other prerequisites set up — here’s an overview. (You can get the detailed version here.)

Install PHPUnit

PHPUnit is distributed via pear. To ensure you are able to retrieve all the necessary components you will want to add the following pear channels:

Writing tests

Once you’ve got a testing environment and the codebase, time to write a test! Tests live in trunk/tests on WordPress.org, or in the tests folder on GitHub.

Create a new test file

When creating new test files, all files should be named ‘test_.php’ (where “test” is the same as the file containing the code being tested). Tests live inside classes named:

class WP_Test_ extends WP_UnitTestCase

where “Test” is the same as the class containing the code to be tested

Write a good test

Here are some good general guidelines for writing unit tests:

Tests should be specific — test one feature at a time.

Tests should be orthogonal (independent) of all other tests. They shouldn’t rely on other tests to run or pass.

Tests should be designed to pass — you’re trying to prove success, not failure.

Tests should be repeatable.

One function may (and probably should) have multiple tests associated with it; one test for each possible condition.

Create a new test every time you find a bug to make sure it’ll be caught if it shows up again in the future.

Use static data in tests to get clear results. Dynamic data can introduce hard-to-diagnose failures

When testing external services, it’s better to re-create the service details (data received, API state, etc) than to connect to the actual service.

Use descriptive names for tests so what’s being tested is clear to everyone; long method names aren’t a problem.

Running tests

Now that you have unit testing setup and you’ve written some specific, clear new tests, it’s time to run ‘em! You should always run the tests locally to ensure your code is working properly before creating a patch or pushing the code into trunk.

Testing with Travis-CI

Failing tests

So your test failed. Now what?

Most importantly, no cheating! Patches submitted with failing tests will not be accepted into trunk. Please don’t try to get around this by removing the test — an unstable patch hurts every site using Jetpack, so we need to be strict about this.

Luckily, PHP Unit tells you which test failed, so you can use that data and update your code to solve the issue. If the failure is with a previously existing function, chances are that your function is interacting with it in a way that is causes failure.

If you’ve tried everything you can think of and your tests continue to fail, ping us directly — we’re happy to help troubleshoot.