Supported technologies: Node.js

The simplest configuration file for node.js looks like:

module.exports = function () {
  return {
    files: [
      'src/**/*.js' // adjust if required
    ],

    tests: [
      'test/**/*.spec.js' // adjust if required
    ],

    env: {
      type: 'node'
    }
  };
};

Node version

If you’d like to use your system default node.js version or any specific locally installed version instead of using the version configured for your IDE or editor, use the env.runner property to specify a command to invoke node or a path to a node executable.

module.exports = function () {
  return {
    files: [
      'lib/**/*.js'
    ],

    tests: [
      'test/**/*Spec.js'
    ],

    env: {
      type: 'node',
      runner: 'node'  // or full path to any node executable
    }
  };
};

Node flags

If you need to pass some node flags, such as --harmony, you may use env.params.runner property for that:

module.exports = function () {
  return {
    files: [
      'lib/**/*.js'
    ],

    tests: [
      'test/**/*Spec.js'
    ],

    env: {
      type: 'node',
      params: {
        runner: '--harmony --harmony_arrow_functions'
      }
    }
  };
};

Environment variables

If you need to pass some process.env variables to the test environment, you may just set them right in the wallaby config file:

module.exports = function () {

  process.env.NODE_ENV = 'development';

  return {
    files: [
      ...
    ],

    tests: [
      ...
    ],

    env: {
      type: 'node'
    }
  };
};

Alternatively, you may use env.params.env property for it:

module.exports = function () {
  return {
    files: [
      'lib/**/*.js'
    ],

    tests: [
      'test/**/*Spec.js'
    ],

    env: {
      type: 'node',
      params: {
        env: 'NODE_PATH=/a/b/c;HOME=/Users/a/b'
      }
    }
  };
};

Files

If you are getting a Cannot find module error or other ‘file not found’ type of issues, please make sure that files that you are trying to load are listed in the config files list. Wallaby.js uses its own cache to process/instrument files and run tests, so it has to copy used files there. Note that this does not apply to the node_modules folder: wallaby.js doesn’t cache it but uses your local version of it. So, no need to list node modules in the files list for your node tests (but it may be required for browser tests if you are using node modules as libs).

Node process reuse

When running your node.js tests, wallaby by default tries to re-use previously created node.js process(es) to make the runs faster. If you are relying on the test node process re-start for each run, because your tests are not cleaning after themselves (for example, they are not closing opened database connections, not stopping started web services, or are registering some callbacks that may be invoked after your test run finishes and interfere with your next test run), then you may use workers.restart setting set to true to make wallaby.js re-start node process for each run.

module.exports = function () {
  return {
    files: [
      'lib/**/*.js'
    ],

    tests: [
      'test/**/*Spec.js'
    ],

    env: {
      type: 'node'
    },

    workers: {
      restart: true
    }
  };
};

Whether you use the setting or not, you will still benefit from wallaby.js incremental test run feature compared to the normal test runner. However, while using the setting allows you to rely on the process re-start and avoid writing any cleanup code, we recommend that you consider adding clean-up code and not recycling node workers, as wallaby.js will be able to run your tests even faster if node processes are reusable.

You can use afterEach hooks of your testing framework to clean up after your tests. Another option is to use the setup function to add some clean-up code that will be executed before each run. In the function, you can make sure your database connection is closed, your web server is stopped, the required node modules cache is cleaned, and any other conditions are met before running your tests.

In case you can not easily reset the state set by some of the node modules, another approach that you may use to reset the state is by resetting node modules cache in your setup function. It will be faster than recycling workers, especially if you find out specific modules to reset the cache for and only delete those from the cache.

For example, to delete a specific module’s cache, you may do:

module.exports = wallaby => {
  return {
    ...
    setup: function (w) {
      delete require.cache[require.resolve('module_with_state')];
    }
  };
};

or, to delete all application specific node modules’ cache, you may do:

module.exports = wallaby => {
  return {
    ...
    setup: function (w) {
      Object.keys(require.cache)
        // you may try only resetting cache for specific modules
        // by filtering them by name
        .filter(function (k) { return ~k.indexOf(w.localProjectDir); }) // && ~k.indexOf('module_with_state')
        .forEach(function (k)  { delete require.cache[k]; });
    }
  };
};

Node process count

By default, wallaby.js automatically decides how many processes to use to run your tests in parallel based on your system capacity. However, sometimes you may need to manually set the number of workers to be used. For example, if your tests are creating an HTTP server that is listening on a certain port (as opposed to using dynamic port allocation for your tests), you may need to set the workers count to 1, because otherwise you may have issues with different test workers trying to create the server on the same port.

module.exports = function () {
  return {
    files: [
      'lib/**/*.js'
    ],

    tests: [
      'test/**/*Spec.js'
    ],

    env: {
      type: 'node'
    },

    workers: {
      initial: 1,
      regular: 1
    }
  };
};

A better approach would be to dynamically allocate ports, so that your tests could run in parallel.

ES modules

Wallaby supports native ECMAScript Modules in relevant versions of node.js, if your testing framework supports them.

You may also use ES6 modules with wallaby in node either with babel/TypeScript to transpile your code to CommonJs, or you may use the standard-things/esm module to enable ES modules support.

To use the standard-things/esm module with Wallaby you will need:

  • npm i --save esm to your project,
  • add the following settings to your wallaby config:
module.exports = function () {
  return {
    ...
    env: {
      type: 'node',
      params: {
        runner: `-r ${require.resolve('esm')}`
      }
    }
  }
};

You may find the full configuration and working sample in this repository.

CoffeeScript and TypeScript

By default, wallaby CoffeeScript and TypeScript compiler for node.js renames .coffee/.ts files to .js files, so the following would work in CoffeeScript:

require './app'

or in TypeScript:

require('./app')

where the original file is app.coffee/app.ts.

If you would like to do it differently and use your own renaming strategy, you may pass the ‘noRename’ option to CS compiler:

'**/*.coffee': w.compilers.coffeeScript({ noRename: true })

or

'**/*.ts': w.compilers.typeScript({ noRename: true, module: 'commonjs' }) // CommonJs modules

and use preprocessors to rename files the way you like:

preprocessors: {
  '**/*.coffee': file => file.rename(file.path + '.js').content
}

or

preprocessors: {
  '**/*.ts': file => file.rename(file.path + '.js').content
}

The preprocessor above will change app.coffee/app.ts to app.coffee.js/app.ts.js so you may require it as

require './app.coffee'

or

require('./app.ts')

Node modules in subfolder

If you have some node modules in a subfolder of your main project folder, you may need to give wallaby.js a hint about how to load them, as wallaby.js is using its own file cache to run your tests and you probably don’t want to copy the node modules there.

For example, if you have a core subfolder with its own node modules, you may add:

var path = require('path');
process.env.NODE_PATH += path.delimiter + path.join(wallaby.localProjectDir, 'core', 'node_modules');

to your configuration file. Wallaby.js will set the setting to all created test workers, so your tests will be able to resolve local node modules from the subfolder.

Mocha

The simplest configuration file for mocha with node.js looks like:

module.exports = function () {
  return {
    files: [
      'src/**/*.js' // adjust if required
    ],

    tests: [
      'test/**/*.spec.js' // adjust if required
    ],

    env: {
      type: 'node'
    }
  };
};

Babel, TypeScript, CoffeeScript

If you are using Babel to transpile you code, you need to add Babel compiler to your Wallaby config. TypeScript is supported with zero configuration required, as well as CoffeeScript.

Mocha --require equivalent

In wallaby.js you may use a setup function that gets executed before your tests to initialize anything you need, including requiring a test helper.

Mocha --file equivalent

In wallaby.js you may use a setup function that gets executed before your tests to initialize anything you need, including a test helper to be loaded before other test files files.

mocha.opts

You may set mocha options (like timeout, ui, grep, slow, etc.) in your wallaby.js config setup function, for example:

module.exports = function () {
  return {
    ...

    setup: function (w) {
      var mocha = w.testFramework;
      mocha.timeout(3000);
    }
  };
};

ES6 node modules

If some of your project’s node modules are using ES6 modules internally, or if you need to compile them with babel for some other reason, you may enable babel-register just for those modules. For example, to enable babel compilation for quill node module, you may do this:

module.exports = function () {
  return {
    ...

    setup: function (w) {
      require('@babel/register')({ only: /quill/ });
    }
  };
};