Mocha tests with extra options or parameters
I am writing test cases for my Node.js application using Mocha. The test cases need an API key as an extra input option or parameter. The API key is private, so I don't want to include it directly in the test files as everyone then can see it on GitHub. I know there are some options available for Mocha at:
http://mochajs.org/#usage
But is it possible to include some parameters to let testers specify their own API key for the test in the commandline? Such as:
./node_modules/mocha/bin/mocha test/*.js --key YOUR_KEY
Solution 1:
I don't think Mocha itself supports passing extra parameters to your tests, but you could use environment variables:
env KEY=YOUR_KEY mocha test/*.js # assumes some sort of Unix-type OS.
And read them in your test files:
var key = process.env.KEY;
Solution 2:
Take a look at the optimist module by Substack and nconf from flatiron. A lot of my tests depend on external parameters and the optimist and nconf modules makes it easy to load configuration options from a json file
In your test command pass the path to the config.json file
test command
mocha test/api-test.js --config=/path/to/config.json --reporter spec
api-test.js
var path = require('path')
var fs = require('fs')
var assert = require('assert')
var argv = require('optimist').demand('config').argv
var configFilePath = argv.config
assert.ok(fs.existsSync(configFilePath), 'config file not found at path: ' + configFilePath)
var config = require('nconf').env().argv().file({file: configFilePath})
var apiConfig = config.get('api')
var apiKey = apiConfig.key
config.json
{
"api": {
"key": "fooKey",
"host": "example.com",
"port": 9000
}
}
Alternative
Another pattern I have been using recently is the config module. You can specify a ./config/default.yml
file for running regularly and a ./config/test.yml
file for tests.
When running your test suite, export NODE_ENV=test and the config module will load test.yml
In your code it is easy to access the configuration object
var config = require('config')
// config now contains your actual configuration values as determined by the process.env.NODE_ENV
var apiKey = config.api.key
An easy way to set NODE_ENV=test is by running your tests with a makefile. Run all your tests via make test
. To run a single test execute make one NAME=test/unit/sample-test.js
Sample makefile
MOCHA?=node_modules/.bin/mocha
REPORTER?=spec
GROWL?=--growl
FLAGS=$(GROWL) --reporter $(REPORTER) --colors --bail
test:
@NODE_ENV="test" \
$(MOCHA) $(shell find test -name "*-test.js") $(FLAGS)
one:
@NODE_ENV="test" \
$(MOCHA) $(NAME) $(FLAGS)
unit:
@NODE_ENV="test" \
$(MOCHA) $(shell find test/unit -name "*-test.js") $(FLAGS)
integration:
@NODE_ENV="test" \
$(MOCHA) $(shell find test/integration -name "*-test.js") $(FLAGS)
acceptance:
@NODE_ENV="test" \
$(MOCHA) $(shell find test/acceptance -name "*-test.js") $(FLAGS)
.PHONY: test
Solution 3:
One of the easiest ways to pass parameters similar to the process.argv[index] method mentioned in this thread is using the npm config variables. This allows you to see the variable name a little more clearly:
test command:
npm --somevariable=myvalue run mytest
package.json:
"scripts": {
"mytest": "mocha ./test.js" }
test.js
console.log(process.env.npm_config_somevariable) // should evaluate to "myvalue"
Solution 4:
The other answers are limited in that they do not support code execution prior to running your test suite. They only support passing parameters.
This answer supports code execution BEFORE your test suite is executed and is fully documented by mocha
mocha docs: http://unitjs.com/guide/mocha.html#mocha-opts
create ./test/mocha.opts
--recursive
--reporter spec
--require ./server.bootstrap
--require ./test/test.bootstrap
create ./server.bootstrap.js
global.appRoot = require('app-root-path');
// any more server init code
create ./test/test.bootstrap.js
process.env.NODE_ENV='test';
// any more test specific init code
finally in your server.js:
require('./server.bootstrap');
DONE!
The code in the server bootstrap will be executed prior to testing and server execution (npm start and npm test)
The code in the test bootstrap will only be executed prior to testing (npm test)
Thanks to @damianfabian for this one - see How to initialise a global variable in unit test runs?