Running Tests

spooning does not provide any “magic” for running tests defined across multiple files (which means that the file that calls run should require any test definition files).

If that sounds like a pain, install spooning-cli to:

  • run all tests in files that match a glob pattern
  • automatically enable color output if the environment supports it
  • set configuration options from command line arguments

For an example of running tests defined in multiple files without the CLI, read on.

Organizing Tests

Many programmers like to group all their tests together in a test folder. For larger projects it can be useful for tests to live alongside the code they are testing. It is a matter of personal preference and what makes sense for a particular project (it doesn’t matter to spooning). This example assumes the following directory structure:

  • my-project/
    • test/
      • src/
        • hello.test.js
        • index.js
      • run.js

Files

hello.test.js

const {test} = require('spooning');

test('Should say hello', (callback) => {
    setTimeout(() => {
        callback(null, 'Hello!');
    }, 100);
});

index.js

require('./hello.test.js');

run.js

#!/usr/bin/env node

const {run, exit} = require('spooning');

require('./src');

run(exit);

Run

Execute node test/run.js to run all the tests in all the files listed in test/src/index.js

Notice that run.js calls run and passes the provided exit callback which will exit the process with an appropriate code when finished.

Options

The run.js file is the appropriate place to set spooning options. For example, to enable parallel test execution and change the output stream to stderr:

#!/usr/bin/env node

const {run, exit, reporter, setConcurrency} = require('spooning');

require('./src');

setConcurrency(10); // run 10 tests at a time

reporter.stream = process.stderr; // write to stderr instead of stdout

run(exit);

Command Line Arguments

If you want to be able to set options on the command line (without using the CLI), see the simple solution below. To parse a more complex argument structure, use an external library like minimist.

const {setBail, setConcurrency, reporter: {tap}, Tap} = require('spooning');

tap.setStyle(Tap.Styles.Unicode);

process.argv.slice(2).forEach((arg) => {
    const concurrencyMatch = arg.match(/(-c|--concurrency)=(\d+)/);
    if (concurrencyMatch) {
        setConcurrency(parseInt(concurrencyMatch[2], 10));
    }
    else if (arg === '--bail') {
        setBail(true);
    }
    else if (arg === '--debug') {
        tap.setDebug(true);
    }
    else if (arg === '--basic-style') {
        tap.setStyle(Tap.Styles.Basic);
    }
    else if (arg === '--no-style') {
        tap.setStyle(Tap.Styles.None);
    }
});

If you only care about boolean flags (i.e. not concurrency), you can use Set:

const args = new Set(process.argv.slice(2));
tap.setDebug(args.has('--debug'));    

Auto-Run

spooning has an auto-run feature which will start running tests as soon as they are defined (as opposed to waiting for run to be called). Enable this feature by calling setAutoRun(true).

auto-run mode has certain limitations which are outlined in the API Documentation.

To ensure that the process exits with a non-zero code if one or more tests fail in auto-run mode, observe the runEnd event:

#!/usr/bin/env node

const spooning = require('spooning');

spooning.on('runEnd', ({exitCode}) => process.exit(exitCode)).setAutoRun(true);

require('./src');

Next Chapter

Continue to Integration for information on using spooning with complementary packages and services.