Writing Unit Tests with Nightwatch

Unit testing in Nightwatch has been refined in version 0.9. Unit tests now written in Nightwatch are also fully compatible with Mocha's Exports interface, so you can use either test runners.

Unit Tests Mode

Nightwatch automatically attempts to connect to the WebDriver server and create a session. When running unit tests this needs to be disabled and the runner needs to be made aware that it is operating in unit testing mode.

This can be done in two ways:

Setting unit_tests_mode=true

This is a global option. Set the unit_tests_mode option to true in the nightwatch.json:

{
  "src_folders" : ["tests"],
  
"unit_tests_mode": true }

Adding @unitTest property per test

You can set the @unitTest property to true if you'd like to have individual test suites as unit tests.

const assert = require('assert');

module.exports = { '@unitTest': true,
'demo UnitTest' : function (done) { assert.equal('TEST', 'TEST'); setTimeout(function() { done(); }, 10); } };

Assertion framework

For unit tests, the browser object is not passed as an argument to the test case. The only argument passed is the done callback to be used for asynchronous tests.

You can use whatever assertion framework you like. Chai.js is quite a good one and very flexible.

Example

Here's a subset of the unit test for the utils.js Nightwatch module:

var assert = require('assert');
var common = require('../../common.js');
var Utils = common.require('util/utils.js');

module.exports = { 'test Utils' : { testFormatElapsedTime : function() {
var resultMs = Utils.formatElapsedTime(999); assert.equal(resultMs, '999ms');
var resultSec = Utils.formatElapsedTime(1999); assert.equal(resultSec, '1.999s');
var resultMin = Utils.formatElapsedTime(122299, true); assert.equal(resultMin, '2m 2s / 122299ms'); },
testMakeFnAsync : function() { function asyncFn(cb) { cb(); }
function syncFn() {}
var convertedFn = Utils.makeFnAsync(1, syncFn); var called = false; convertedFn(function() { called = true; });
assert.equal(Utils.makeFnAsync(1, asyncFn), asyncFn); assert.ok(called); } } };

Asynchronous Unit Tests

The argument to the test function is the optional done callback which signals the test is complete. If present, the callback must be called when the async operation finishes.

Example

Here's unit test which checks if Nightwatch throws an error if you don't invoke the done callback within a set time (10 ms).


module.exports = {
  const assert = require('assert');
  
module.exports = { 'demo UnitTest' : function (done) { assert.equal('TEST', 'TEST');
setTimeout(function() { done(); }, 10); } }; };

Using a Combined Configuration

Below is an example of how you can combine end-to-end tests and unit tests in the same nightwatch.json configuration file. Notice the usage of exclude and filter properties.

An empty exclude means we want to reset its value and rely only on filter.

{
  "src_folders" : ["./examples/tests", "./examples/unittests"],
  "output_folder" : "./examples/reports",
  

"webdriver" : { "start_process": true, "server_path": "node_modules/.bin/chromedriver", "port": 9515 },
"test_settings" : { "default" : { "launch_url" : "http://localhost", "desiredCapabilities": { "browserName": "chrome" }, "exclude" : "./examples/unittests/*" },
"unittests" : { "unit_tests_mode" : true, "filter" : "./examples/unittests/*", "exclude" : "" } } }

Code Coverage

At the moment, Nightwatch doesn't provide a coverage reporter but it is something that's being planned for a future release. In the meantime you can write a custom reporter which will output coverage data. See the custom reporter section for details and the Mocha HTMLCov reporter for how the reporter should look like.

3rd party coverage service

There are some hosted services which provide the reporting and metrics for you in a modern web interface. These services will typically require coverage data in LCOV format. Nightwatch uses coveralls.io.

For details on how an LCOV reporter should look like and how to integrate with your project, you can check out the mocha-lcov-reporter.