JavaScript Unit Tests for Core

Recently WordPress added QUnit as a JavaScript unit testing framework and added its first JavaScript unit tests. I thought I would walk through how to run the tests and how to write tests so that we can increase our JavaScript test coverage. All of these are based upon using the develop.svn.wordpress.org checkout which is where the JS unit tests live.

How to run our unit tests

You have two options for running our unit tests. They can be run using grunt from the command line or using the browser. Once you have develop.svn.wordpress.org/trunk checked out, and the latest version of node.js installed (v0.10.18 as of this writing), install grunt-cli globally by running

sudo npm install -g grunt-cli

then install the node packages the WordPress build tools depend upon by running

npm install

You are now ready to run the tests from the command line by running

grunt test

As long as your tests pass, this will generate a report that looks like:

$ grunt test
Running "qunit:files" (qunit) task
Testing tests/qunit/index.html ......OK
>> 42 assertions passed (929ms)

Done, without errors.

If there is a failure, you’ll be notified of the test the failed and the exact assertion that failed (useful for when your test has multiple assertions).

You can also run the unit tests in a browser by having a server serve the tests/qunit/ directory. Then when you visit the page in the brower, all of your tests will run and you’ll get a nice report that looks like

Screen Shot of WordPress QUnit tests

look at all those tests passing

You can click on an individual tests to see each of the assertions.
The individual assertions of one of the tests expanded

How to write JS unit tests

Writing unit tests is fun and easy(on JavaScript written in a unit testable way)! We’ll start by assuming the file you will be adding tests for isn’t already included in our unit tests. If it is, you can skip to step three.

  1. Add the javascript files and any dependency files from WordPress to the “Tested files” section of tests/qunit/index.html.
  2. Add a file that matches the name to /tests/qunit in a directory structure equal to the src directory. For example, the /src/wp-admin/js/password-strength-meter.js file’s unit tests are found at tests/qunit/wp-admin/js/password-strength-meter.js. Then add this file to the “Unit tests” section of tests/qunit/index.html
  3. Now that are files are ready, let’s start adding tests. The Password Strength Unit Tests are a good place to look to see this in action. The test file is a closure that encapsulates each module. We’ll start by defining the module that are working with. This should be a unique name to make it easier to see when a test fails.
  4. Each test begins with a call to the test function. The first parameter is the name of the test, the second optional parameter is the number of assertions that will be in that test, and the third is a function that contains those assertions. Thus the first line of your tests will look something like
    test( 'mismatched passwords should return 5', function() {
  5. Inside this function, you can do anything you need to prepare for your assertions. When you are ready, you can call any assertions you want to make. The most common assertions are:
    • OK which checks to make sure that the asserted value is true. This is equivalent to the phpunit assertion assertTrue
    • equal which checks to make sure that an expected value is equal to what you want it to be. This is what you should use for things like strings, integers, and floating point numbers. It is not a strict test, so if you want to ensure that the type is also what you can expect, use strictEqual. This is similar to the phpunit assertion assertTrue.
    • deepEqual Is similiar to equal, but does a recursive comparison of the the expected and actual value. This is good for testing arrays, objects, regular expressions, dates and functions.
  6. if you need html elements for your tests, you can set them up in the qunit-fixture div inside index.html

Much of the JavaScript in WordPress core right now wasn’t written with unit tests in mind and thus might need some refactoring to be more testable. Simple files such word-count.js should require the least amount of work to be made unit testable.

For more information on QUnit, check out the QUnit documentation. Happy Unit Testing.

props @aaroncampbell and @nacin for helping me with this post