• Stars
    star
    1,899
  • Rank 24,431 (Top 0.5 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 14 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Easy unit testing in node.js and the browser, based on the assert module.

Nodeunit

Build Status

Simple syntax, powerful tools. Nodeunit provides easy async unit testing for node.js and the browser.

DEPRECATED PROJECT

The project is very stale. We've kept it working on new versions of node, and sometimes merged small PRs that help teams relying on nodeunit.

Nodeunit was the arguably first testing framework developed for node. It was very useful at the time, but there's an overwhelming number of other worthwhile testing solutions out there that are actively maintained. tap, ava, tape, mocha, jasmine, jest, ... the list goes on and on.

If Nodeunit were truly bringing some different philosophy to the testing scene I'd say yes effort should be made to shore up it's development, but given how many other great options there are out there, a benefit of letting it atrophy is it's one less choice people have to make when choosing a testing solution. You are strongly encouraged to check out other more modern testing options.

Features

  • Simple to use
  • Just export the tests from a module
  • Works with node.js and in the browser
  • Helps you avoid common pitfalls when testing asynchronous code
  • Easy to add test cases with setUp and tearDown functions if you wish
  • Flexible reporters for custom output, built-in support for HTML and jUnit XML
  • Allows the use of mocks and stubs

Contributors

Also, check out gerad's nodeunit-dsl project, which implements a 'pretty dsl on top of nodeunit'.

More contributor information can be found in the CONTRIBUTORS.md file.

Usage

Here is an example unit test module:

exports.testSomething = function(test) {
    test.expect(1);
    test.ok(true, "this assertion should pass");
    test.done();
};

exports.testSomethingElse = function(test) {
    test.ok(false, "this assertion should fail");
    test.done();
};

When run using the included test runner, this will output the following:

Installation

There are two options for installing nodeunit:

  1. Clone / download nodeunit from github, then:

    make && sudo make install

  2. Install via npm:

    npm install nodeunit -g

API Documentation

Nodeunit uses the functions available in the node.js assert module:

  • ok(value, [message]) - Tests if value is a true value.
  • equal(actual, expected, [message]) - Tests shallow, coercive equality with the equal comparison operator ( == ).
  • notEqual(actual, expected, [message]) - Tests shallow, coercive non-equality with the not equal comparison operator ( != ).
  • deepEqual(actual, expected, [message]) - Tests for deep equality.
  • notDeepEqual(actual, expected, [message]) - Tests for any deep inequality.
  • strictEqual(actual, expected, [message]) - Tests strict equality, as determined by the strict equality operator ( === )
  • notStrictEqual(actual, expected, [message]) - Tests strict non-equality, as determined by the strict not equal operator ( !== )
  • throws(block, [error], [message]) - Expects block to throw an error.
  • doesNotThrow(block, [error], [message]) - Expects block not to throw an error.
  • ifError(value) - Tests if value is not a false value, throws if it is a true value. Useful when testing the first argument, error in callbacks.

Nodeunit also provides the following functions within tests:

  • expect(amount) - Specify how many assertions are expected to run within a test. Very useful for ensuring that all your callbacks and assertions are run.
  • done() - Finish the current test function, and move on to the next. ALL tests should call this!

Nodeunit aims to be simple and easy to learn. This is achieved through using existing structures (such as node.js modules) to maximum effect, and reducing the API where possible, to make it easier to digest.

Tests are simply exported from a module, but they are still run in the order they are defined.

Note: Users of old nodeunit versions may remember using ok, equals and same in the style of qunit, instead of the assert functions above. These functions still exist for backwards compatibility, and are simply aliases to their assert module counterparts.

Asynchronous Testing

When testing asynchronous code, there are a number of sharp edges to watch out for. Thankfully, nodeunit is designed to help you avoid as many of these pitfalls as possible. For the most part, testing asynchronous code in nodeunit just works.

Tests run in series

While running tests in parallel seems like a good idea for speeding up your test suite, in practice I've found it means writing much more complicated tests. Because of node's module cache, running tests in parallel means mocking and stubbing is pretty much impossible. One of the nicest things about testing in javascript is the ease of doing stubs:

var _readFile = fs.readFile;
fs.readFile = function(path, callback) {
    // it's a stub!
};
// test function that uses fs.readFile

// we're done
fs.readFile = _readFile;

You cannot do this when running tests in parallel. In order to keep testing as simple as possible, nodeunit avoids it. Thankfully, most unit-test suites run fast anyway.

Explicit ending of tests

When testing async code it's important that tests end at the correct point, not just after a given number of assertions. Otherwise your tests can run short, ending before all assertions have completed. It's important to detect too many assertions as well as too few. Combining explicit ending of tests with an expected number of assertions helps to avoid false test passes, so be sure to use the test.expect() method at the start of your test functions, and test.done() when finished.

Groups, setUp and tearDown

Nodeunit allows the nesting of test functions:

exports.test1 = function (test) {
    ...
}

exports.group = {
    test2: function (test) {
        ...
    },
    test3: function (test) {
        ...
    }
}

This would be run as:

test1
group - test2
group - test3

Using these groups, Nodeunit allows you to define a setUp function, which is run before each test, and a tearDown function, which is run after each test calls test.done():

module.exports = {
    setUp: function (callback) {
        this.foo = 'bar';
        callback();
    },
    tearDown: function (callback) {
        // clean up
        callback();
    },
    test1: function (test) {
        test.equals(this.foo, 'bar');
        test.done();
    }
};

In this way, it's possible to have multiple groups of tests in a module, each group with its own setUp and tearDown functions.

Running Tests

Nodeunit comes with a basic command-line test runner, which can be installed using sudo make install. Example usage:

nodeunit testmodule1.js testfolder [...]

If no entry file specified, test defaults.

The default test reporter uses color output, because I think that's more fun :) I intend to add a no-color option in future. To give you a feeling of the fun you'll be having writing tests, lets fix the example at the start of the README:

Ahhh, Doesn't that feel better?

When using the included test runner, it will exit using the failed number of assertions as the exit code. This means it exits with 0 when all tests pass.

Command-line Options

  • --reporter FILE - you can set the test reporter to a custom module or on of the modules in nodeunit/lib/reporters, when omitted, the default test runner is used.
  • --list-reporters - list available built-in reporters.
  • --config FILE - load config options from a JSON file, allows the customisation of color schemes for the default test reporter etc. See bin/nodeunit.json for current available options.
  • -t testName - run specific test only.
  • -f fullTestName - run specific test only. fullTestName is built so: "outerGroup - .. - innerGroup - testName".
  • --version or -v - report nodeunit version
  • --help - show nodeunit help

Running tests in the browser

Nodeunit tests can also be run inside the browser. For example usage, see the examples/browser folder. The basic syntax is as follows:

test.html

<html>
  <head>
    <title>Example Test Suite</title>
    <link rel="stylesheet" href="nodeunit.css" type="text/css" />
    <script src="nodeunit.js"></script>
    <script src="suite1.js"></script>
    <script src="suite2.js"></script>
  </head>
  <body>
    <h1 id="nodeunit-header">Example Test Suite</h1>
    <script>
      nodeunit.run({
        'Suite One': suite1,
        'Suite Two': suite2
      });
    </script>
  </body>
</html>

Here, suite1 and suite2 are just object literals containing test functions or groups, as would be returned if you did require('test-suite') in node.js:

suite1.js

this.suite1 = {
    'example test': function (test) {
        test.ok(true, 'everything is ok');
        test.done();
    }
};

If you wish to use a commonjs format for your test suites (using exports), it is up to you to define the commonjs tools for the browser. There are a number of alternatives and it's important it fits with your existing code, which is why nodeunit does not currently provide this out of the box.

In the example above, the tests will run when the page is loaded.

The browser-version of nodeunit.js is created in dist/browser when you do, make browser. You'll need UglifyJS installed in order for it to automatically create nodeunit.min.js.

Adding nodeunit to Your Projects

If you don't want people to have to install the nodeunit command-line tool, you'll want to create a script that runs the tests for your project with the correct require paths set up. Here's an example test script, that assumes you have nodeunit in a suitably located node_modules directory.

#!/usr/bin/env node
var reporter = require('nodeunit').reporters.default;
reporter.run(['test']);

If you're using git, you might find it useful to include nodeunit as a submodule. Using submodules makes it easy for developers to download nodeunit and run your test suite, without cluttering up your repository with the source code. To add nodeunit as a git submodule do the following:

git submodule add git://github.com/caolan/nodeunit.git node_modules/nodeunit

This will add nodeunit to the node_modules folder of your project. Now, when cloning the repository, nodeunit can be downloaded by doing the following:

git submodule init
git submodule update

Let's update the test script above with a helpful hint on how to get nodeunit, if it's missing:

#!/usr/bin/env node
try {
    var reporter = require('nodeunit').reporters.default;
}
catch(e) {
    console.log("Cannot find nodeunit module.");
    console.log("You can download submodules for this project by doing:");
    console.log("");
    console.log("    git submodule init");
    console.log("    git submodule update");
    console.log("");
    process.exit();
}

process.chdir(__dirname);
reporter.run(['test']);

Now if someone attempts to run your test suite without nodeunit installed they will be prompted to download the submodules for your project.

Built-in Test Reporters

  • default - The standard reporter seen in the nodeunit screenshots
  • minimal - Pretty, minimal output, shows errors and progress only
  • html - Outputs a HTML report to stdout
  • junit - Creates jUnit compatible XML reports, which can be used with continuous integration tools such as Hudson.
  • machineout - Simple reporter for machine analysis. There is nodeunit.vim which is useful for TDD on VIM.

Writing a Test Reporter

Nodeunit exports runTest(fn, options), runModule(mod, options) and runFiles(paths, options). You'll most likely want to run test suites from files, which can be done using the latter function. The options argument can contain callbacks which run during testing. Nodeunit provides the following callbacks:

  • moduleStart(name) - called before a module is tested
  • moduleDone(name, assertions) - called once all test functions within the module have completed (see assertions object reference below) ALL tests within the module
  • testStart(name) - called before a test function is run
  • testReady(test) - called before a test function is run with the test object that will be passed to the test function
  • testDone(name, assertions) - called once a test function has completed (by calling test.done())
  • log(assertion) - called whenever an assertion is made (see assertion object reference below)
  • done(assertions) - called after all tests/modules are complete

The assertion object:

  • passed() - did the assertion pass?
  • failed() - did the assertion fail?
  • error - the AssertionError if the assertion failed
  • method - the nodeunit assertion method used (ok, same, equals...)
  • message - the message the assertion method was called with (optional)

The assertionList object:

  • An array-like object with the following new attributes:
    • failures() - the number of assertions which failed
    • duration - the time taken for the test to complete in msecs

For a reference implementation of a test reporter, see lib/reporters/default.js in the nodeunit project directory.

Sandbox utility

This is a function which evaluates JavaScript files in a sandbox and returns the context. The sandbox function can be used for testing client-side code or private un-exported functions within a module.

var sandbox = require('nodeunit').utils.sandbox;
var example = sandbox('example.js');

sandbox(files, sandbox) - Evaluates JavaScript files in a sandbox, returning the context. The first argument can either be a single filename or an array of filenames. If multiple filenames are given their contents are concatenated before evaluation. The second argument is an optional context to use for the sandbox.

Note: When working with the sandbox if your script depends on outside sources (i.e. using require) then you will want to pass that into the optional context when setting up the sandbox.

var sandbox = require('nodeunit').utils.sandbox;
// pass in some node globals
var box_globals = {
    // Passing module.exports into the sandbox will give your code  access to it.
    module: {exports: exports},
    // Passing require into the sandbox will give your code  access to use it AND
    // will share the cache with modules already required from outside the sandbox.
    require: require,
    // Passing console into the sandbox will give your code access to it
    console: console
};
var example = sandbox('example.js', box_globals);

Running the nodeunit Tests

The tests for nodeunit are written using nodeunit itself as the test framework. However, the module test-base.js first does some basic tests using the assert module to ensure that test functions are actually run, and a basic level of nodeunit functionality is available.

To run the nodeunit tests do:

make test

Note: There was a bug in node v0.2.0 causing the tests to hang, upgrading to v0.2.1 fixes this.

machineout reporter

The default reporter is readable for human but not for machine analysis. When you want to analyze the output of nodeunit, use machineout reporter and you will get

nodeunit with vim

There is nodeunit.vim so you can use nodeunit with VIM.

That compiler uses machineout reporter and it is useful to use with vim-makegreen.

Contributing

Contributions to the project are most welcome, so feel free to fork and improve. When submitting a pull request, please run make lint first to ensure we're following a consistent coding style.

More Repositories

1

async

Async utilities for node and the browser
JavaScript
28,095
star
2

highland

High-level streams library for Node.js and the browser
JavaScript
3,427
star
3

jam

JavaScript package manager - using a browser-focused and RequireJS compatible repository
JavaScript
1,497
star
4

forms

An easy way to create, parse and validate forms in node.js
JavaScript
1,010
star
5

pithy

An internal DSL for generating HTML in JavaScript
JavaScript
435
star
6

nimble

A really tiny functional JavaScript and async flow-control library
JavaScript
329
star
7

petrify

A flexible static site generator for node.js
JavaScript
259
star
8

cookie-sessions

Secure cookie-based session middleware for Connect
JavaScript
97
star
9

quip

A chainable API for response objects in node
JavaScript
92
star
10

dispatch

A regular expression URL dispatcher for Connect
JavaScript
84
star
11

magery

JavaScript templates for progressive enhancement
JavaScript
56
star
12

copykitten

Tiny immutable JSON data structures
JavaScript
40
star
13

jquery.notify.js

Ubuntu-style notifications within a web browser
JavaScript
25
star
14

couchr

Lightweight CouchDB request library for Node and the browser
JavaScript
22
star
15

hoodie-drawing

Hoodie drawing demo app
JavaScript
20
star
16

cpm

CouchDB Package Manager - a tool for the management of CouchApps and associated libraries
JavaScript
16
star
17

wmd

wanton markdown - a markdown parser based on showdown
JavaScript
15
star
18

blog

CouchApp code used to run my blog
JavaScript
15
star
19

tamawiki

I'm learning Rust!
Rust
13
star
20

chicken-toml

A TOML parser for CHICKEN Scheme built with comparse
Scheme
11
star
21

docker-hoodie

Basic docker file for trying out hoodie
Shell
10
star
22

bootstrap-less

Kanso package providing uncompiled less files for bootstrap with images and js as attachments
JavaScript
10
star
23

behaviors

A (really) simple way to check a modules export's in node.js. Inspired by behaviors in Erlang.
JavaScript
9
star
24

snowy

HTTP server for CHICKEN Scheme
C
8
star
25

events

Browser port of the node.js events module
JavaScript
8
star
26

lolcorp

Intentionally insecure example Node.js applications
JavaScript
7
star
27

raspberry-pi-gpio

Raspberry Pi GPIO library for CHICKEN Scheme
Scheme
6
star
28

scrawl

Dumb comment parsing
JavaScript
6
star
29

pithy2

A Typescript-friendly and human-friendly API for building DOM elements
TypeScript
5
star
30

snake

Snake game for the BBC micro:bit
Python
5
star
31

erlmpd

An Erlang client module for MPD
Erlang
5
star
32

chicken-leveldb

CHICKEN Scheme bindings to LevelDB
Scheme
5
star
33

python-magery

Python implementation of Magery templates
Python
5
star
34

highland-couchr

Highland streams style API to CouchDB, using couchr under the hood
JavaScript
4
star
35

mutiny

Rust
4
star
36

chicken-sodium

CHICKEN Scheme bindings to libsodium crypto library
Scheme
3
star
37

0

3
star
38

ghstats

allows you to compare github users followers and project watchers
JavaScript
3
star
39

couchr-browser

Lightweight library for making CouchDB requests, based on jQuery
JavaScript
2
star
40

couchi

CouchDB command-line interface
JavaScript
2
star
41

magery-tests

Test suite for server implementations of Magery templates
HTML
2
star
42

chat

Kanso chat app
JavaScript
2
star
43

lmdb-lolevel

Low-level CHICKEN Scheme bindings to LMDB, closely following the C API
Scheme
2
star
44

condor

C O N D O R
JavaScript
2
star
45

chicken-level

abstract API layer for chicken-leveldb
Scheme
2
star
46

gamejam

First Play Sheffield Game Jam!
JavaScript
2
star
47

chicken-ldap-bind

Implements LDAP bind for authentication using OpenLDAP
Scheme
2
star
48

library

CouchApp for storing templates
JavaScript
2
star
49

chicken-gumbo

C binding to the Gumbo HTML parser for CHICKEN Scheme
Scheme
2
star
50

dust

P2P event streams
Scheme
2
star
51

users-core

Core resources for the users app, must be used with a theme (eg, users-default)
JavaScript
2
star
52

gh-label-dashboard

An example of using the github search API to query labels across all repositories in an organisation
1
star
53

validatejs

JavaScript
1
star
54

webhook-test

1
star
55

users-default

Default bootstrap theme for users app
1
star
56

chicken-sublevel

Namespaced access to leveldb implementations
Scheme
1
star
57

chicken-level-sexp

Automatically read and write s-expressions to leveldb
Scheme
1
star
58

chicken-fnmatch

Test filenames against shell wildcard patterns using fnmatch
Scheme
1
star
59

jambot

IRC bot for #jamjs
JavaScript
1
star
60

mochiproxy

Easily proxy mochiweb requests, based on the CouchDB proxy module
Erlang
1
star
61

highland-couchdb-alldocs

Provides Highland streams for reading all keys/docs in a CouchDB database
JavaScript
1
star