Mocha v6 adds Configuration File Support & Drops Node.js v4.x
The next major release of Mocha, v6.0.0, will be released "in the near future." Since it contains significant changes to command-line flags and configuration, we're being cautious and plan on publishing one or more prerelease versions.
Any prerelease versions will be installable via npm install mocha@next
.
Notably, given Mocha's commitment to only supporting maintained versions of Node.js, Mocha v6.0.0 will drop support for Node.js v4.x.
But the big story is configuration file support! Let's start with a little history.
mocha.opts
The need for configuration was recognized early in Mocha's history.
Before v6, the way you'd "configure" Mocha for command-line use would be to create a mocha.opts
file. This file would contain actual command-line flags which would be essentially grafted on to Node.js' process.argv
Array. These flags would then be combined with any user-supplied command-line arguments, then passed to the secondary _mocha
executable. This is how Mocha is able to provide "direct" support for Node.js flags--by invoking a child node
process.
I'd call this method of "configuring" a command-line app "unusual" at best; no effort was made to intelligently reconcile mocha.opts
with user-supplied arguments. It was easy to encounter conflicts or other bad weirdness when using mocha.opts
.
Several years ago, we knew that Mocha needed actual honest-to-goodness configuration files. A lack of maintenance resources meant it just wasn't a high priority.
Meanwhile, technical debt kept accumulating around Mocha's command-line option parsing. Coupled with new features in Node.js (e.g., process.allowedNodeEnvironmentFlags
), it became pragmatic to refactor this system.
Option Parrrsing
With v6, Mocha adopts the powerful yargs for argument parsing. It offers features and control that Mocha had been missing, and ultimately provides not just a better developer experience, but a better experience for the user of Mocha.
yargs just so happens to support configuration ("RC") files and loading of options via package.json
out-of-the-box. Since we were already shredding the option-parsing code, this refactor became a great opportunity to tackle Mocha's "configuration" problem.
Even if it was a great opportunity, it was still more work than anticipated! This article is not a post-mortem, however. In the end, it was worth the effort, and I think Mocha's users will appreciate it.
With the help of yargs, Mocha v6 supports configuration via JS, JSON, or YAML RC file, package.json
and mocha.opts
.
Introducing .mocharc.whatever
Instead of (or in addition to, if you please) mocha.opts
, Node.js users of Mocha can now create a .mocharc.js
, .mocharc.json
, .mocharc.yml/yaml
, or add a mocha
property to a package.json
. This is the same kind of thing that, say, ESLint supports (though not identical).
Here's an example mocharc.yaml
containing Mocha's defaults:
diff: true
extension:
- js
opts: ./test/mocha.opts
package: ./package.json
reporter: spec
slow: 75
timeout: 2000
ui: bdd
This can be JSON instead:
{
"diff": true,
"extension": ["js"],
"opts": "./test/mocha.opts",
"package": "./package.json",
"reporter": "spec",
"slow": 75,
"timeout": 2000,
"ui": "bdd"
}
If you please, that same JSON could be in the mocha
property of your package.json
. If you need some special logic, here's the same in JavaScript:
module.exports = {
diff: true,
extension: ['js'],
opts: './test/mocha.opts',
package: './package.json',
reporter: 'spec',
slow: 75,
timeout: 2000,
ui: 'bdd'
};
Each option name corresponds to a command-line option as listed in mocha --help
(which has also been overhauled).
Things to Know about Options
- On the command-line, any boolean flag can be negated by prepending
--no-
to the flag. For example,--no-diff
will disable diffs. This is appropriate formocha.opts
. But in a configuration file, you should usediff: false
or its equivalent. You could useno-diff: true
, but that's silly, right? - Any option of type
array
(usemocha --help
to see these) can be specified multiple times. These will be concatenated, so arequire: esm
in your.mocharc.yml
and a--require my-thing
on the command-line will result in"require": ["my-thing, "esm"]
. Command-line arguments will be shifted on to the array. - Mocha loads config using the following priority: command-line args first, RC file second,
package.json
third,mocha.opts
fourth, and then finally Mocha's own defaults. - To specify a test file or directory in an options file, use the
spec
option. If you care about order, usefile
instead. - Aliases are allowed in config files; see these in Mocha's "help" output.
- When run via
mocha
, Node.js and V8 flags are also supported in configuration files andpackage.json
(mocha.opts
already did this). - Any V8 flag can be supplied by prepending
--v8-
to the flag name. For example, if you wanted--randomize-hashes
, that'd be--v8-randomize-hashes
on the command line, orv8-randomize-hashes: true
in a YAML config. Only supported when running Mocha viamocha
. - Mocha only supports the flags your current version of
node
supports. Again, only supported when running Mocha viamocha
. - Unknown flags/options are ignored;
--butts
does nothing
Try It Out!
Some example config files are available in the repo, and our documentation (unfortunately) already reflects these changes.
When released--likely this week--I encourage you to check out the first prerelease of Mocha v6, which should be version 6.0.0-0
, installable via npm i mocha@next
.