Question

I'm using mocha for javascript unit-testing now.

I have several test files, each file has a before and beforeEach, but they are exactly the same.

How do I provide a global before and beforeEach for all of them (or some of them)?

Was it helpful?

Solution

Declare a before or beforeEach in a separate file (I use spec_helper.coffee) and require it.

spec_helper.coffee

afterEach (done) ->
  async.parallel [
    (cb) -> Listing.remove {}, cb
    (cb) -> Server.remove {}, cb
  ], ->
    done()

test_something.coffee

require './spec_helper'

OTHER TIPS

In the root of the test folder, create a global test helper test/helper.js which has your before and beforeEach

// globals
global.assert = require('assert');

// setup
before();
beforeEach();

// teardown
after();
afterEach();

from the mocha documentation

ROOT-LEVEL HOOKS

You may also pick any file and add “root”-level hooks. For example, add beforeEach() outside of all describe() blocks. This will cause the callback to beforeEach() to run before any test case, regardless of the file it lives in (this is because Mocha has an implied describe() block, called the “root suite

All regular describe()-suites are first collected and only then run, this kinda guarantees this being called first.

'use strict'
let run = false

beforeEach(function() {
    if ( run === true ) return
    console.log('GLOBAL ############################')
    run = true
});

Remove the run-flag, if you want to see it run each time, before every test.

I named this file test/_beforeAll.test.js. It has no need to be imported/required anywhere, but the .test. (resp. .spec.) in the filename is important, so that your testrunner picks it up…


bonus track 8-): using mocha.opts \o/

If there's stuff, you truly only want to set up once before running your tests (regardless which ones...), mocha.opts is a surprisingly elegant option! – Just add a require to your file (yes, even if it contributes little to mocha, but rather to your test setup). It will run reliably once before:

enter image description here

( in this example I detect, if a single test or many tests are about to run. In the former case I output every log.info(), while on a full run I reduce verbosity to error+warn... )

Update:

If someone knows a way, to access some basic properties of the mocha suite that is about to be run in once.js, I would love to know and add here. (i.e. my suiteMode-detection is lousy, if there was another way to detect, how many tests are to be run…)

I've had similar issue when I needed to "mock" global variables used by one of dependencies.

I used .mocharc.js for that, since code in that JS file is being executed once when "mocha" environment is being setup.

Example .mocharc.js:

global.usedVariable = "someDefinedValue";

/** other code to be executed when mocha env setup **/

module.exports = {};

This worked for me, nevertheless this looks quite "dirty" way to do that. Please, comment if you know a better place for that code :)

mochaHooks root hook plugin minimal example on Mocha 8

This mechanism is currently documented at: https://mochajs.org/#root-hook-plugins

It does not work for before, only for beforeEach however, since before is not in the list of available hooks from: https://mochajs.org/#available-root-hooks

Here's a demo:

test/global.js

// Root hook.
exports.mochaHooks = {
  beforeEach(done) {
    console.log('mochaHooks.beforeEach');
    done();
  },
};

// Bonus: global fixture, runs once before everything.
exports.mochaGlobalSetup = async function() {
  console.log('mochaGlobalSetup');
};

test/mytest.js

var assert = require('assert');

describe('describe0', function() {
  // Only runs before the current describe.
  before(async () => {
    console.error('before describe 0');
  });
  beforeEach(async () => {
    console.error('beforeEach describe 0');
  });
  it('it 0 0', function() {
    assert.equal(0, 0);
  });
  it('it 0 1', function() {
    assert.equal(0, 0);
  });

  describe('describe 0 0', function() {
    before(async () => {
      console.error('before describe 0 0');
    });
    beforeEach(async () => {
      console.error('beforeEach describe 0 0');
    });
    it('it 0 0 0', function() {
      assert.equal(0, 0);
    });
    it('it 0 0 1', function() {
      assert.equal(0, 0);
    });
  });

  describe('describe 0 1', function() {
    before(async () => {
      console.error('before describe 0 1');
    });
    beforeEach(async () => {
      console.error('beforeEach describe 0 1');
    });
    it('it 0 1 0', function() {
      assert.equal(0, 0);
    });
    it('it 0 1 1', function() {
      assert.equal(0, 0);
    });
  });
});

Then you enable that file with --require:

npx mocha --require test/global.js test/

Outcome:

mochaGlobalSetup


  describe0
before describe 0
mochaHooks.beforeEach
beforeEach describe 0
    ✓ it 0 0
mochaHooks.beforeEach
beforeEach describe 0
    ✓ it 0 1
    describe 0 0
before describe 0 0
mochaHooks.beforeEach
beforeEach describe 0
beforeEach describe 0 0
      ✓ it 0 0 0
mochaHooks.beforeEach
beforeEach describe 0
beforeEach describe 0 0
      ✓ it 0 0 1
    describe 0 1
before describe 0 1
mochaHooks.beforeEach
beforeEach describe 0
beforeEach describe 0 1
      ✓ it 0 1 0
mochaHooks.beforeEach
beforeEach describe 0
beforeEach describe 0 1
      ✓ it 0 1 1


  6 passing (6ms)

So we see that the global hook ran before every local beforeEach.

For before I couldn't find a better solution than defining a helper and calling it from every before: How can I make Mocha load a helper.js file that defines global hooks or utilities?

Tested on mocha 8.3.2, Node v14.16.0.

The use of a modules can make it easier to have a global setup/teardown for your test suite. Here is an example using RequireJS (AMD modules):

First, let's define a test environment with our global setup/teardown:

// test-env.js

define('test-env', [], function() {
  // One can store globals, which will be available within the
  // whole test suite.
  var my_global = true;

  before(function() {
    // global setup
  });
  return after(function() {
    // global teardown
  });
});

In our JS runner (included in mocha's HTML runner, along the other libs and test files, as a <script type="text/javascript">…</script>, or better, as an external JS file):

require([
          // this is the important thing: require the test-env dependency first
          'test-env',

          // then, require the specs
          'some-test-file'
        ], function() {

  mocha.run();
});

some-test-file.js could be implemented like this:

// some-test-file.js

define(['unit-under-test'], function(UnitUnderTest) {
  return describe('Some unit under test', function() {
    before(function() {
      // locally "global" setup
    });

    beforeEach(function() {
    });

    afterEach(function() {
    });

    after(function() {
      // locally "global" teardown
    });

    it('exists', function() {
      // let's specify the unit under test
    });
  });
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top