Mocha: path to mocha.opts with -f

Mocha is a wonderful (:D) test framework which allows you to write really understandable tests in JavaScript. I’ve already introduced it in a previous article, so today I’ll focus on a pull request I’ve proposed.

Like other programs, you can pass arguments to mocha, like for instance –reporter used to specified a way to display test results. By the way, you should try once the nyan reporter. Concerning mocha, it’s also possible to set arguments in a file named « mocha.opts ». Interesting feature, but the file must absolutely be stored in your test directory.

So the idea is to add an argument: -f, –fileconf <path>. Furthermore, the –fileconf option allows you to specify the configuration file that will be used, by default “/test/mocha.opts”; allowing you to store your configuration file anywhere you wanted. This modification is very useful if you make tests using the same configuration file in many directories. Without –fileconf, you have to copy your file in each directory, and even a small modification must be done on each file. Using -f, you store the mocha.opts file in a unique place, so that any modifications of the file would immediatly impact all tests.

About the code

Add the parameter with commander:

.option('-f,--config <path>','specify the path to configuration file')

Load the file using commander to parse the command line:

//-f, --config
program.parse(process.argv);
var pathConf = 'test/mocha.opts';
if (program.config && exists(program.config)) {
  pathConf = program.config;
}
try {
  var opts = fs.readFileSync(pathConf, 'utf8')
    .trim()
    .split(/\s+/);

  process.argv = process.argv
    .slice(0, 2)
    .concat(opts.concat(process.argv.slice(2)));
} catch (err) {
  // ignore
}

In fact, this code is not available in mocha yet since « parsing twice might have some strange side-effects »…

An other way to augment argv without using commander:

//-f, --config

var pathConf = 'test/mocha.opts'
  , fIndex = process.argv.indexOf('-f')
  , configIndex = process.argv.indexOf('--config');

if(fIndex !== -1 && exists(process.argv[fIndex + 1]) ) {
  pathConf = process.argv[fIndex + 1];
}

if(configIndex !== -1 && exists(process.argv[configIndex + 1]) ) {
  pathConf = process.argv[configIndex + 1];
}

And I’ll finished this article by quoting visionmedia:

Maybe it’s ok but that’s still pretty hacky.

Test Js avec Mocha et Chai

Deux outils bien utiles pour réaliser des fichiers de tests. Mocha est framework de test écrit en Javascript et une bibliothèque d’assertion pour Node

Avec Mocha, on peut facilement décrire sa situation de test puis vérifier l’état des différents tests liés à celle-ci.
Plusieurs dispositions sont disponibles pour l’affichage des résultats des tests. Pour ma part, j’utilise le reporter « spec ».
Il est également possible de préparer l’environnement de test en utilisant before ou after par exemple, pour effectuer des actions avant les situations de test.

Chai nous permet quant à lui de vérifier et comparer la valeur de variables ou de propriétés avec la valeur attendue dans le cas d’un fonctionnement « normal ».
Différentes possibilités d’écriture, le style assert ou le style BDD décliné en deux colorations: expect et should.

Pour l’utilisation d’assert: var assert = require(‘chai’).assert;

Un petit exemple de test combinant Mocha et Chai.

var assert = require('chai').assert,
question = undefined,
answer = 42;

describe('Question of Life and the Universe', function() {
  it('answer to this undefined question should be 42', function(done) {
    assert.isUndefined(question, 'Answer is 42, but what is the question');
    assert.equal(answer, 42);
    done();
  });
});

Sur cette exemple, il est possible d’enchaîner les it dans un même describe et les describe dans un fichier de test.
Notons qu’il est également possible de faire un describe dans un describe.

Chaque test possède un temps max pour être réalisé, par défaut 200ms il me semble.
Il est possible de modifier ce temps de timeout à l’appel de la commande mocha via le paramètre dédié.
Sinon, on peut spécifier le timeout pour chaque it grâce à this.timeout(tpsEnMs); .

Autre point intéressant, la présence de done comme paramètre de function au niveau du it change la caractère synchrone ou asynchrone de votre test.
Avec done, mocha ne passe au it suivant que lorsque le it en cours à renvoyé done.
Inversement, omettre done pour un it permet donc à mocha de continuer automatiquement sur le test suivant.

Pour conclure, le duo Mocha/Chai permet d’avoir des fichiers de test avec une hiérarchie lisible. Le fonctionnement et la syntaxe viennent rapidement.
Enfin, avoir transformé une batterie de test écrit en vows en tests utilisant Mocha et Chai, m’a montré qu’utiliser le duo que je viens de présenter simplifie beaucoup les choses.