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/ });
}
};
};