ES6 is coming…

Some of you may have heard about ES6 (ECMAScript 6), the next version of the ECMAScript language specifications. If you’re a web developer and haven’t heard about this, then it’s time to wake up and get some read on the Internet about it, cause it will revolutionize the way you write JavaScript, whether it’s for browsers or for NodeJS.

… faster than you think !

But even if ES6 will not land tomorrow, there is an advantage about starting to learn it right now : you can already use it (no lies). Tools like Traceur allow you to type JavaScript using upcoming features from ES6, and then compile it into JavaScript-of-today that browsers and NodeJS already understand.

If you plan to do or are already doing a web app or anything else written in ES6, you may want to write units tests too, to test your code. But how do you write units tests for ES6 code ? Do they have to be written in ES6 too ? No. Then how do you fill the gap between your ES6 sources and unit tests written in ES5 ? In this post, I’ll show you how to achieve that using Traceur as bridge between ES6 and ES5 code. Unit tests will be written using nodeunit, but I’m pretty sure that the solution could work with most of the testing frameworks.

Requirements

Install Traceur and nodeunit if you haven’t already :

npm install traceur
npm install nodeunit

I’m not using the --save option cause my project’s root folder has no package.json file. If yours do, you probably want to use this option so these packages will be registered in your project’s dev dependencies.

Tests for a simple ES6 module

First, let’s assume that you have the following ES6 code :

/* Returns an integer representation of `val`. */
export function int(val) {
 return val | 0;
};

And the following units tests written in ES5 :

var to = require('./../../data/to.js');

module.exports = {
  int: function(assert) {
    assert.equal(6, to.int(6));
    assert.equal(6, to.int(6.3));
    assert.equal(6, to.int(6.9));
    assert.equal(6, to.int('6'));
    assert.equal(6, to.int('6.3'));
    assert.equal(6, to.int('6.9'));

    assert.done();
  }
};

If you run node_modules/nodeunit/bin/nodeunit tests/data/to.js now, you’ll get a SyntaxError: Unexpected reserved word on the word export, obviously. To fix that, just add those 5 lines of code at the top of your tests file :

var traceur = require('traceur');

traceur.require.makeDefault(function(filename) {
  return filename.indexOf('node_modules') === -1;
});

var to = require('./../../data/to.js');

module.exports = {
  int: function(assert) {
    assert.equal(6, to.int(6));
    assert.equal(6, to.int(6.3));
    assert.equal(6, to.int(6.9));
    assert.equal(6, to.int('6'));
    assert.equal(6, to.int('6.3'));
    assert.equal(6, to.int('6.9'));

    assert.done();
  }
};

And you’re done ! You just told Traceur to replace the default require() function with its own, allowing you to require ES6 modules which will be automatically parsed and their equivalent ES5 code returned.

Now run the tests again by typing node_modules/nodeunit/bin/nodeunit tests/data/to.js in the console and you should see :


to.js
✔ int

OK: 6 assertions (414ms)

Hope that helped.

If you want to follow ES6’s implementation progress, you can check the compatibility table here.

2 thoughts on “How to write unit tests for ES6 code using NodeJS & Traceur

Leave a comment