42b1686025eb4415cf2e8e20776bde967c5cbf89.svn-base 15.2 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
Nodeunit
========

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

* 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__

* [alexgorbatchev](https://github.com/alexgorbatchev)
* [alexkwolfe](https://github.com/alexkwolfe)
* [azatoth](https://github.com/azatoth)
* [kadirpekel](https://github.com/kadirpekel)
* [lambdalisue](https://github.com/lambdalisue)
* [luebken](https://github.com/luebken)
* [orlandov](https://github.com/orlandov)
* [Sannis](https://github.com/Sannis)
* [sstephenson](https://github.com/sstephenson)
* [thegreatape](https://github.com/thegreatape)
* [mmalecki](https://github.com/mmalecki)
* and thanks to [cjohansen](https://github.com/cjohansen) for input and advice
  on implementing setUp and tearDown functions. See
  [cjohansen's fork](https://github.com/cjohansen/nodeunit).

Also, check out gerad's [nodeunit-dsl](https://github.com/gerad/nodeunit-dsl)
project, which implements a 'pretty dsl on top of nodeunit'.

More contributor information can be found in the
[CONTRIBUTORS.md](https://github.com/caolan/nodeunit/blob/master/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:

<img src="https://github.com/caolan/nodeunit/raw/master/img/example_fail.png" />

Installation
------------

There are two options for installing nodeunit:

1. Clone / download nodeunit from [github](https://github.com/caolan/nodeunit),
   then:

    make && sudo make install

2. Install via npm:

    npm install nodeunit

API Documentation
-----------------

Nodeunit uses the functions available in the node.js
[assert module](http://nodejs.org/docs/v0.4.2/api/assert.html):

* __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){
        // its 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 its 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. Its 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, its 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 [...]

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:

<img src="https://github.com/caolan/nodeunit/raw/master/img/example_pass.png" />

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. Exiting 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 build-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.
* __--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 its 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](https://github.com/mishoo/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 its 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](http://hudson-ci.org/).
* __machineout__ - Simple reporter for machine analysis. There is [nodeunit.vim](https://github.com/lambdalisue/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
* __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
evalution. The second argument is an optional context to use for the sandbox.


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 really readable for human but for machinally analysis. 
When you want to analyze the output of nodeunit, use __machineout__ reporter and you will get

<img src="https://github.com/caolan/nodeunit/raw/master/img/example_machineout.png" />


nodeunit with vim
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There is [nodeunit.vim](https://github.com/lambdalisue/nodeunit.vim) so you can use nodeunit with VIM.
That compiler use __machineout__ reporter and it is useful to use with [vim-makegreen](https://github.com/reinh/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.