When writing JavaScript applications or websites a lot of developers write unit tests to ensure the code does what it is supposed to do. The hottest code uses ES6 and transpiles to ES5 with Babel. Mocha is pretty popular as a testing framework these days. Bringing these tools together can be cumbersome. Here is how you do it.
My work on JavaScript applications usually includes writing unit tests.
With some of my latest projects I wrote my JavaScript applying some of ES6's sugar and utilize Babel with Browserify to transpile the code to ES5.
Setting up a testing infrastructure with Mocha I discovered some impediments which I had to work around. Let’s have a look at the details.
ES6 Modules
ES6 Modules provide a way for developers to define dependencies between different JavaScript files. Modules export certain properties for other programs to use. These programs can import whole modules or their functionality selectively. ES6 Modules are designed to replace current dependency management approaches as AMD and CommonJS.
If you want to know more about ES6 Modules, read Axel Rauschmayer's article.
Example Module and Spec
Here is an example module and specification.
Testflow
[module]
[module] --> app/index.js --> test/index.js <-- Mocha
[module] ^
Babel
Browserify and Babel
Compiling with Browserify using Babel is pretty easy. You just need to run
browserify -t [ babelify ] app/index.js -o dist/index.js
This requires browserify
and babelify
to be installed:
npm i --save browserify babelify
You can now use the first command as a script in your package.json
.
I cover the usage of npm as a build tool in another article.
With this we have set up the ES6-to-ES5 compile step which generates a new file which we can use in out application. The next step is to set up testing with Mocha.
Testing with Mocha
You can install Mocha – it's always the same – with npm. You need an assertion library too. I use Chai. You can install both tools like this:
npm i --save mocha chai
Running tests with mocha is as easy as
mocha test/index.js
If you don’t use ES6 and don’t need to transpile to ES5 you’re done with the Mocha setup. Otherwise you will have to do more.
There is an option for Mocha to treat JS as ES6: --harmony
. Unfortunately this
does not implement ES6 Modules and other features. This is why we want to use
Babel to be utilized by Mocha to compile JavaScript. Mocha has an option
--compilers
which helps with this:
mocha --compilers js:babel/register test/index.js
Now Mocha compiles JavaScript while running and we’re save to use the latest ES6 features.
Furthermore we need an initial file which is our entry point for Mocha running
on Node.js. I named this file test/index.js
, as you can see.
All it does is it requires Chai and the test suites:
global.chai = require('chai');
global.expect = global.chai.expect;
// Load test suites
require('../module.spec.js');
You can do more test specific stuff here as for example bootstrapping jsdom.
Test Coverage with Istanbul
It gets a bit tricky if you want to generate coverage reports using
Istanbul. You need to pass the
compiler to the files you want to test and use _mocha
instead of mocha
in
order to get it to use Babel to compile the JS.
istanbul cover _mocha -- --compilers js:babel/register test/index.js
If you don’t use ES6 and don’t need to transpile to ES5 you can use
istanbul cover mocha test/index.js
Don't forget to install Istanbul:
npm i --save istanbul
To exclude the specification file from the coverage report you can pass the
option -x
to Istanbul:
istanbul cover _mocha -x '**/*.spec.js' -- --compilers js:babel/register test/index.js
Conclusion
If you searched Google for an hour to fix this workflow and you can finally use all nice features ES6 provides, setting up Mocha with Babel is totally worth it. But luckily I have already done this search.
Have you used Mocha with the latest ES6 features? Which tools did you use? Let me know and tweet me at @drublic.