Running the same mocha test multiple times with different data

A basic approach to run the same test with different data is to repeat the test in a loop providing the data:

describe('my tests', function () {
  var runs = [
    {it: 'options1', options: {...}},
    {it: 'options2', options: {...}},
  ];

  before(function () {
    ...
  });

  runs.forEach(function (run) {
    it('does sth with ' + run.it, function () {
      ...
    });
  });
});

before runs, well, before all its in a describe. If you need to use some of the options in before, do not include it in the forEach loop because mocha will first run all befores and the all its, which is probably not wanted. You can either put the whole describe in the loop:

var runs = [
  {it: 'options1', options: {...}},
  {it: 'options2', options: {...}},
];

runs.forEach(function (run) {
  describe('my tests with ' + run.it, function () {
    before(function () {
      ...
    });

    it('does sth with ' + run.it, function () {
      ...
    });
  });
});

If you do not wish to pollute your tests with multiple describes, you can use the controversial module sinon for this matter:

var sinon = require('sinon');

describe('my tests', function () {
  var runs = [
    {it: 'options1', options: {...}},
    {it: 'options2', options: {...}},
  ];

  // use a stub to return the proper configuration in `beforeEach`
  // otherwise `before` is called all times before all `it` calls
  var stub = sinon.stub();
  runs.forEach(function (run, idx) {
    stub.onCall(idx).returns(run);
  });

  beforeEach(function () {
    var run = stub();
    // do something with the particular `run.options`
  });

  runs.forEach(function (run, idx) {
    it('does sth with ' + run.it, function () {
      sinon.assert.callCount(stub, idx + 1);
      ...
    });
  });
});

Sinon feels dirty but is effective. Several aid modules such as leche are based on sinon, but arguably introducing further complexity is not necessary.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)