Mocha: Feature proposal: global setup and teardown

Created on 3 Dec 2014  Â·  16Comments  Â·  Source: mochajs/mocha

When testing a server code base and wishing to generate code coverage via an external tool such as istanbul it does not make sense to start and stop the server for every test suite using before and after - especially if there are a lot of test suites and the server performs various operations when starting.

I propose adding the ability to configure a setup function to be invoked asynchronously before any tests are executed and a teardown function after all test suites have been executed.

Whilst I have read CONTRIBUTING.md and imagine this feature is unlikely to be accepted as it may not be a common use case, I have implemented, tested and integrated this functionality with a real project, full details are in the (squashed) commit:

https://github.com/socialally/mocha/commit/fd744e480fa4acbc0846cdaa41f866034bdd38ab

If the consensus is that this feature would be useful to other people and a PR would be accepted then I will issue a PR with the linked commit.

feature

Most helpful comment

Isn't this functionality already possible using the global suite's hooks?

$ cat setup.js
before(function() {
  console.log('global setup');
});

after(function() {
  console.log('global teardown');
});

$ cat test.js
describe('suite', function() {
  it('test', function() {});
});

dstjules:~/git/mocha (master=)
$ mocha test.js setup.js

global setup

  ․global teardown


  1 passing (10ms)

All 16 comments

@freeformsystems This has been asked for before (#1403); our take was that are reasonable workarounds.

The reason we aren't accepting many PRs at the moment is simply that we don't have enough resources to maintain more code.

This may be a handy feature, but unless there is no viable workaround, I can't see it getting merged soon. If you wish to contribute, I could use comments/suggestions on #1457--once that is in place, you wouldn't need code in Mocha core to get this working for you.

it's not just that we don't have the resources. it's also to keep mocha as simple as possible, and it's api small.

this feature does sound useful however i think so i'm not ruling it out.

(@travisjeffery Keeping Mocha simple is great, and if we can provide users with an API to build with if they _do_ want some fancy feature, everybody will be happy. Right now I see a lot of disgruntled users because they have no recourse other than a PR.)

I'll reopen this.

ya we having an api is clearly the best thing for everyone

@boneskull, checked out #1403. The solution spawning processes before and after doesn't help with my code coverage, adding gulp to the stack just for this seems unnecessary when every testing framework I have used has this functionality.

As far as I am aware this is very, very standard functionality for executing tests and think it should be included in mocha (although fully aware my implementation is crude).

With regard to #1457 I would love to help but am really stacked with commercial work at the moment, however having looked around the code a bit it appears to me there are no tests for the browser based test-runner - is that correct? If so the first thing I would do before any refactoring is improve the test suite (integrate with karma) and check the code coverage.

I have thought a little about the plugin refactoring and will try to add some comments soon.

I also requested something similar in #1370. This would be great - especially for cleaning up mocks/stubs, or verifying that all expectations were run.

Isn't this functionality already possible using the global suite's hooks?

$ cat setup.js
before(function() {
  console.log('global setup');
});

after(function() {
  console.log('global teardown');
});

$ cat test.js
describe('suite', function() {
  it('test', function() {});
});

dstjules:~/git/mocha (master=)
$ mocha test.js setup.js

global setup

  ․global teardown


  1 passing (10ms)

@danielstjules,

That looks good if it works, I'll check it out. Interestingly your example output does not show the test suite being executed (test.js)? Does mocha accept multiple [file] arguments i think it is a single glob pattern?

Mocha handles both glob patterns and explicitly listing file arguments.

And the output above is showing the test suite being executed, but I used the dot reporter. Note the dot before the second "global". Here's with the spec reporter:

$ mocha --reporter spec test.js setup.js


global setup
  suite
    ✓ test

global teardown

  1 passing (10ms)

I'm thinking we could update the docs to make it known that this is possible. :)

@danielstjules I think I saw that in there the other night when I was working on the jekyll stuff.

screen shot 2015-04-18 at 10 51 25 am

You're right - just found it under the asynchronous code section. It might be worth emphasizing in another section, or in the wiki somewhere.

Closing for now, as the root before() and after() hooks seem to satisfy the requirements. :)

If I'm not mistaken, having a global before/after will get called for each describe block, is that correct? If so, how could one run something once before and once after the entire test suite runs (not for each describe)? Eg connect to a db when the suite starts (and block until connected) and disconnect after done

If I'm not mistaken, having a global before/after will get called for each describe block, is that correct?

Nope, just at the start/end of the test suite :)

before(function() {
  console.log('before');
});

after(function() {
  console.log('after');
});

describe('suite1', function() {
  it('test', function() {});
});

describe('suite2', function() {
  it('test', function() {});
});
  suite1
    ✓ test

  suite2
    ✓ test

after

  2 passing (9ms)

sorry for necromancing on this issue:
is this behaviour specific to the bdd interface? using tdd (loaded via karma-mocha) I observe that setup/teardown at the root level are invoked for every suite and every test. Quite the opposite of what is desired here.

edit:
after some more digging through issues, it turns out that the equivalents of before and after for tdd are suiteSetup and suiteTeardown

Isn't this functionality already possible using the global suite's hooks?

$ cat setup.js
before(function() {
  console.log('global setup');
});

after(function() {
  console.log('global teardown');
});

$ cat test.js
describe('suite', function() {
  it('test', function() {});
});

dstjules:~/git/mocha (master=)
$ mocha test.js setup.js

global setup

  ․global teardown


  1 passing (10ms)

That works pretty well in most scenarios, anyone have any idea how to run those before and after hooks in watch mode?

Was this page helpful?
0 / 5 - 0 ratings