This entry is part 6 of 12 in the series Server-Side JavaScript, Pintura, and Persevere 2.0

Patr (Promise-based Asynchronous Test Runner) is a simple lightweight cross-platform test runner for promised-based applications. Patr executes tests by simply executing functions of an object and is intended to be used in combination with the “assert” module (which is available on NodeJS and Narwhal), so tests can be as simple as:

var assert = require("assert");
tests = {
  testSomething: function(){
    assert.eq(3, 3);
  }
}
require("patr/runner").run(tests);

Creating asynchronous tests is easy as well. Inspired by Dojo’s DOH test runner for returning a promise from tests, we don’t need a new interface to indicate when an asynchronous test is completed. The promise’s completion or failure indicates the completion or failure of the test. This allows us to elegantly pipe asynchronous operations through to the test runner. Here is an example of an asynchronous test:

var fs = require("promised-io/fs");
require("patr/runner").run({
    testFile: function(){
        return fs.readFile("my-file.txt")  // asynchronously read the file
            .then(function(contents){ // next action in promise flow
                // make an assertion
                assert(contents.toString(), "expected contents of the file");
            });
    };
});

Now this test will asynchronously read the file, make an assertion, and when completed the returned promise will notify the test runner that the test is complete (or failed) and continue on to the next test.

Tests can be organized into groups by simply creating nested objects:

require("patr/runner").run({
    testGroupA: {
      testFile: function(){
        ..
      },
      ..
    },
    testGroupB: {
      testAnother: function(){
      ....
    }
});

(Also, remember all your test properties must start with “test”.)

The recommended approach for creating test modules is to use the exports object to hold tests. This makes it very easy to run a test module directly or as part of a group. For example:

//something.js:
var assert = require("assert");
exports.testSomething: function(){
    assert.eq(3, 3);
};

if (require.main === module)
    require("patr/runner").run(exports);

Now we can directly run this module to run these tests. We can also include this module in another set of tests:

//all-tests.js:
exports.testSomething = require("./something");
exports.testAnotherGroupOf = require("./more-tests");
if(require.main === module){
    require("patr/runner").run(exports);
}

We now have each of these tests within a sub group for easy execution of groups of tests at any level in the hierarchy (all the tests or individual groups).

Performance Testing

Patr is also great for performance testing. You can set an iterations flag with in a test group or from the command line to run through the test a specified number of iterations and give performance statistics.

Summary

Patr is a lightweight test runner that makes it extremely simple to create test suites and hierarchies with idiomatic JavaScript and asynchronous tests with promises. Patr is built on Promised-IO, so it is ready for cross-platform execution, including Node, Narwhal, and within the web browser.