Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

TDD framework for node

branch: master

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 bin
Octocat-spinner-32 deps
Octocat-spinner-32 lib
Octocat-spinner-32 test
Octocat-spinner-32 .gitignore
Octocat-spinner-32 .gitmodules
Octocat-spinner-32 History.md
Octocat-spinner-32 Makefile
Octocat-spinner-32 Readme.md
Octocat-spinner-32 package.json
Octocat-spinner-32 seed.yml
Readme.md

Expresso

TDD framework for nodejs.

Expresso is an extremely fast Test Driven Development framework for nodejs. I was frustrated with what was currently available, I wanted something fast (not executed serially), with reasonable reporting, drop-dead simple async support (you dont have to do anything!), and code coverage.

Features

  • intuitive async support
  • intuitive test runner executable
  • test coverage support and reporting
  • uses the assert module
  • assert.eql() alias of assert.deepEqual()
  • assert.response() http response utility
  • assert.includes()
  • assert.isNull()
  • assert.isUndefined()
  • assert.isNotNull()
  • assert.isNotUndefined()
  • assert.match()
  • assert.length()
  • light-weight

Installation

To install both expresso and node-jscoverage run:

$ make install

To install expresso alone (no build required) run:

$ make install-expresso

Install via kiwi:

$ kiwi install expresso

Install via npm:

$ npm install expresso

Examples

To define tests we simply export several functions:

module.exports = {
    'test String#length': function(assert){
        assert.equal(6, 'foobar');
    }
}

Async example:

exports['test async] = function(assert, beforeExit){
    var n = 0;
    setTimeout(function(){
        ++n;
        assert.ok(true);
    }, 200);
    setTimeout(function(){
        ++n;
        assert.ok(true);
    }, 200);
    beforeExit(function(){
        assert.equal(2, n, 'Ensure both timeouts are called');
    });
}

Executable Usage

To run a single test suite (file) run:

$ expresso test/a.test.js

To run several suites we may simply append another:

$ expresso test/a.test.js test/b.test.js

We can also pass a whitelist of tests to run within all suites:

$ expresso --only "foo()" --only "bar()"

Or several with one call:

$ expresso --only "foo(), bar()"

Globbing is of course possible as well:

$ expresso test/*

When expresso is called without any files, test/* is the default, so the following is equivalent to the command above:

$ expresso

If you wish to unshift a path to require.paths before running tests, you may use the -I or --include flag.

$ expresso --include lib test/*

The previous example is typically what I would recommend, since expresso supports test coverage via node-jscoverage (bundled with expresso), so you will need to expose an instrumented version of you library.

To instrument your library, simply run node-jscoverage, passing the src and dest directories:

$ node-jscoverage lib lib-cov

Now we can run our tests again, using the lib-cov directory that has been instrumented with coverage statements:

$ expresso -I lib-cov test/*

The output will look similar to below, depending on your test coverage of course :)

Test Coverage
+--------------------------------+----------+------+------+--------+
| filename                       | coverage | LOC  | SLOC | missed |
+--------------------------------+----------+------+------+--------+
| a.js                           |    90.00 |   26 |   10 |      1 |
| b.js                           |   100.00 |   12 |    5 |      0 |
+--------------------------------+----------+------+------+--------+
                                 |    93.33 |   38 |   15 |      1 |
                                 +----------+------+------+--------+

bar.js:

  1 |   | 
  2 | 1 | exports.bar = function(msg){
  3 | 1 |     return msg || 'bar';
  4 |   | };


foo.js:

   1 |   | 
   2 | 1 | exports.foo = function(msg){
   3 | 2 |     if (msg) {
   4 | 0 |         return msg;
   5 |   |     } else {
   6 | 2 |         return generateFoo();
   7 |   |     }
   8 |   | };
   9 |   | 
  10 | 1 | function generateFoo() {
  11 | 2 |     return 'foo';
  12 |   | }
  13 |   | 
  14 | 1 | function Foo(msg){
  15 | 0 |     this.msg = msg || 'foo';
  16 |   | }

To make this process easier expresso has the -c or --cov which essentiall does the same as the two commands above. The following two commands will run the same tests, however one will auto-instrument, and unshift lib-cov, and the other will run tests normally:

$ expresso -I lib test/*
$ expresso -I lib --cov test/*

Currently coverage is bound to the lib directory, however in the future --cov will most likely accept a path.

HTTP Server Response Assertions

Expresso 0.3.0 adds the assert.response() which accepts a Server instance, followed by the request options, response assertions, and final optional assertion msg.

The Server passed should NOT be bound to a port, assert.response() will assign a dummy port ranging from --port NUM and up (defaults to 5000).

assert.response(server, {
    url: '/',
    method: 'GET'
},{
    body: '{"name":"tj"}',
    status: 200,
    headers: {
        'Content-Type': 'application/json; charset=utf8'
    }
});

assert.response(server, {
    url: '/foo',
    method: 'POST',
    data: 'bar baz'
},{
    body: '/foo bar baz',
    status: 200
}, 'Test POST');


assert.response(server, {
    url: '/'
}, function(res){
    assert.ok(res.body.indexOf('tj') >= 0, 'Test assert.response() callback');
});

Dropbox fails lots but here is an image with the colored output :)

node coverage

Something went wrong with that request. Please try again.