Javascript Unit Tests with TravisCI and QUnit

I wanted to make an update to my Bingo Card Generator. Previously I’d added automated tests for JSHint via TravisCI to test for code formatting, but now I wanted to actually test code functionality. I decided to add a simple unit test using QUnit.

I made a lot of mistakes trying to get this to work (probably because I didn’t read the documentation!), so I’ve included all my steps and missteps below in case they are useful to someone else:

I installed qunit in my development environment:

npm --global install qunit

I created a test folder in my project:

mkdir test

I added a simple test:

removeEmptyElements = function (arr) {
    "use strict";
    var newArray = [], i = 0;
    for (i = 0; i < arr.length; i += 1) {
        if (arr[i]) {
            newArray.push(arr[i]);
        }
    }
    return newArray;
}

QUnit.test("RemoveEmptyElements", function(assert) {
	"use strict";
	var testInput = ",,,A,,B,,,C,";
	var testArray = testInput.split(",")
	var cleanedArray = removeEmptyElements(testArray);
	assert.equal(cleanedArray.length, 3, "Array has 3 elements")
    assert.ok(cleanedArray[0] === "A", "First element is A");
    assert.ok(cleanedArray[1] === "B", "Second element is B");
    assert.ok(cleanedArray[2] === "C", "Third element is C");
});

The test runs in my development environment:

$ qunit
TAP version 13
ok 1 RemoveEmptyElements
1..1
# pass 1
# skip 0
# todo 0
# fail 0

Now, how do I integrate this new test with TravisCI?

First, I added qunit to devDependencies in package.json:

  "devDependencies": {
    "jshint": "^2.6.0",
    "quinit": "^2.6.1"
  },

Then I tried adding qunit to scripts in package.json:

  "scripts": {
    "jshint": "./node_modules/jshint/bin/jshint images.js",
    "qunit": "./node_modules/qunit/bin/qunit"
  }

I committed the changes to my local git repo and pushed them to GitHub. This triggered TravisCI to run tests, which failed:

npm ERR! code E404
npm ERR! 404 Not Found: quinit@^2.6.1

OK, maybe I’m not the greatest typist. That should be qunit, not quinit.

After that fix I received a different message from TravisCI:

> BingoCardGenerator@0.0.2 test /home/travis/build/cherdt/BingoCardGenerator
> echo 'Error: no test specified'
Error: no test specified

TravisCI says it passed, but no tests were run. It turns out the scripts object in package.json needs to contain a test element (I thought I was being more descriptive by calling the elements jshint and qunit):

  "scripts": {
    "test": "./node_modules/jshint/bin/jshint images.js",
    "test": "./node_modules/qunit/bin/qunit"
  }

This led to a new problem. I had anticipated that two key-value pairs with identical keys (test) might be an issue. Only the qunit test ran, no sign of jshint in the TravisCI output.

This is when I finally decided to read some documentation. If you want to run multiple test engines, you need a script to trigger each of them. See the section Implementing Complex Build Steps in the TravisCI documentation.

I created a bash script to run both jshint and qunit:

#!/bin/bash

IS_FAILED=0

echo "Running jshint..."
if jshint images.js simulation.js
then
	echo "jshint passed!"
else
	echo "jshint failed!"
	IS_FAILED=1
fi
echo

echo "Running qunit tests..."
if qunit
then
	echo "qunit tests passed"
else
	echo "qunit tests failed"
	IS_FAILED=1
fi
echo

exit $IS_FAILED

I added that script as the test in packages.json:

  "scripts": {
    "test": "sh ./test.sh"
  }

Note that TravisCI uses the exit code of this script to determine if you have a passing or failing build. The TravisCI example uses set -ev in the bash script; the -e option will cause the script to exit on any error. (If the error occurred in the first test, though, you might not see the results of subsequent tests, so I decided to run the qunit tests even if jshint failed.)

That worked — both tests ran and everything passed!

I decided to make one more change. I moved test.sh to scripts/run-tests.sh (to match the TravisCI example). I also updated packages.json accordingly:

  "scripts": {
    "test": "sh .scripts/run-tests.sh"
  }

This time it failed! TravisCI displayed the following error:

sh: 0: Can't open .scripts/run-tests.sh

Of course! That’s a bad path. I updated it to:

  "scripts": {
    "test": "sh ./scripts/run-tests.sh"
  }

Everything works! Now I just need to write more unit tests.

Leave a Reply

Your email address will not be published. Required fields are marked *