global before/after/beforeEach/afterEach?

8,533 views
Skip to the first unread message

deitch

unread,
4 Sept 2012, 06:54:5304/09/2012
to moc...@googlegroups.com
Is there any way to do a global (i.e. across all files in ./tests/) before/after/beforeEach/afterEach?

Let's say my tests dir looks like:

you.js
me.js
him.js
her.js

Before any of the tests in any of the files run, I have a "global" before that will start various servers (this is for integration testing, as opposed to stubbed units); after all of them are complete, I have a "global" after that shuts them down.

Before each of the tests in any files runs, I have a "global" beforeEach that resets various data; after each of the tests runs, I have a "global" afterEach (although this is less necessary).

I could, in theory, run mocha programmatically, run my global before before calling mocha.run(), and pass my global after to the callback of mocha.run(callback). But it would be nice to do this using the standard setup.
Similarly, I could wrap the entire set in each you.js, me.js, etc. test file by calling the same beforeEach which I require from another file, but it would be nice to do it using the standard setup.

Or am I thinking about this the wrong way?

vision media [ Tj Holowaychuk ]

unread,
4 Sept 2012, 11:31:4304/09/2012
to moc...@googlegroups.com
yeah just have one file and put before/after etc in it, if they're at the root-level they run for everything

deitch

unread,
4 Sept 2012, 11:33:1204/09/2012
to moc...@googlegroups.com, t...@vision-media.ca
Kind of restrictive if I have all one file. I have a lot of tests, want to break them up by file.

vision media [ Tj Holowaychuk ]

unread,
4 Sept 2012, 11:34:0704/09/2012
to moc...@googlegroups.com
yeah you can do that, what I'm saying is there's one "root" suite regardless of how many files you have, before/after etc at the root-level are added to that root suite

deitch

unread,
4 Sept 2012, 11:37:4304/09/2012
to moc...@googlegroups.com, t...@vision-media.ca
Time for me to show my ignorance. How do I do that? I though it just runs all files in ./tests/ and that's it. Didn't know of root and that it can automatically include others.

Can you give me a sample?

deitch

unread,
5 Sept 2012, 05:36:1905/09/2012
to moc...@googlegroups.com, t...@vision-media.ca
I tried recursive subdirs, but that just loads them all. Did you mean to do it programmatically, by having my root file load all the other files (i.e. replicate what addFile and loadFiles do in mocha)?

vision media [ Tj Holowaychuk ]

unread,
5 Sept 2012, 11:30:4805/09/2012
to moc...@googlegroups.com
just pick any file and put beforeEach(function(){}) in it etc, it'll be invoked per test-case

deitch

unread,
5 Sept 2012, 11:43:5505/09/2012
to moc...@googlegroups.com, t...@vision-media.ca
Dang, TJ, this is great! If I have a file in there that has before/after *outside* of any describe(), then the before gets run before any describe, and the after before any after.

If I have a file that has beforeEach/afterEach *outside* of any describe(), then the beforeEach gets run before every single test, all the way into recursion, and the afterEach after every single test.

You really need to document this on http://visionmedia.github.com/mocha, it is very powerful.

vision media [ Tj Holowaychuk ]

unread,
5 Sept 2012, 12:10:0405/09/2012
to moc...@googlegroups.com
added a mention to it :D

deitch

unread,
6 Sept 2012, 07:43:2306/09/2012
to moc...@googlegroups.com, t...@vision-media.ca
Related but slightly different question: Is there any way to wrap a directory in a describe? E.g. let's say you have a full suite of tests for UI, and another for server. A clean way to do this would be:

test/
  ui/
    test1.js
    html.js
    other.js
  server/
    test2.js
    foo.js
    something.js

I could wrap each file in server/ with describe('server',function(){...}) and each in ui/ with describe('ui',function(){...}), but that is very inefficient.

Is there any way to say, "this directory and its children are implicit describe('ui')"?

Then I can easily do 

mocha -g "ui"

Domenic Denicola

unread,
6 Sept 2012, 11:22:5106/09/2012
to <mochajs@googlegroups.com>
Just run mocha against only one set of tests at a time (i.e. only pass it one directory).

deitch

unread,
6 Sept 2012, 19:07:3506/09/2012
to moc...@googlegroups.com
Now why didn't I think of that? The obvious answer staring us in the face....

Thanks!

Charitha Reddy

unread,
31 May 2013, 02:49:3431/05/2013
to moc...@googlegroups.com
Hi,

I am also trying to run integration tests using mocha. So, trying to solve the same problem which you faced. Like how to pass data to the test before doing mocha.run(). The data here is related to server, so I can know the data only before running the test based on which server is free. I need to pass this data to the server. How did you solve the problem of passing the data to the test file just before mocha runs the test file.

Thanks.

Avi Deitcher

unread,
31 May 2013, 02:52:0831/05/2013
to moc...@googlegroups.com
I ended up running it programmatically. I wrote a "launch harness" for mocha that does all the setup and tear down I need. So I never run 'mocha'. Instead I run my own run.js script with its own options (most of which are passed through):

node ./run.js options...



I should probably extract it, and then build it into mocha itself as a pull request.... when I find time.




--
You received this message because you are subscribed to a topic in the Google Groups "Mocha" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mochajs/5zZ0CwpobeQ/unsubscribe?hl=en-GB.
To unsubscribe from this group and all of its topics, send an email to mochajs+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



Eric Saboia

unread,
31 Jan 2014, 08:32:2731/01/2014
to moc...@googlegroups.com
deitch,

You can use before/after root level to run a single time before all your suite.

Just create a Makefile like this:

deitch

unread,
1 Feb 2014, 13:42:5101/02/2014
to moc...@googlegroups.com
Yep, that's what I did in the end, based on TJ's input. Works like a charm.

Ifiok Jr.

unread,
17 Apr 2014, 16:54:3717/04/2014
to moc...@googlegroups.com, t...@vision-media.ca
This method doesn't seem to work when using a coffeescript compiler. 

It may be a problem with my implementation, but I'm guessing it's because the coffeescript is compiled with the top-level function wrapper. It could easily be solved if using the bare option, but looking at the code I don't think that can be added when running tests via mocha https://github.com/visionmedia/mocha/blob/master/bin/_mocha#L262

Any suggestions?

Ifiok Jr.

unread,
19 Apr 2014, 13:57:5019/04/2014
to moc...@googlegroups.com, t...@vision-media.ca
I had a look again today, and managed to get around the problem I encountered by making one of the variables in my `before (done) ->` callback a global variable. This solved it for me.

It was actually a Sails v0.10.0-rc5 server that I was testing with mocha and coffeescript. Here's the configuration that got it working for me, in case it helps anyone. Without setting the app object to be global my tests couldn't access it. 


# tests/test_init.coffee
Sails = require 'sails/lib/app'
global.app = Sails()


before (done) ->
  # Lift app and store the app reference
  app.lift
    # Basic options you should pretty much always use for tests:
    # turn down the log level so we can view the test results
    log:
      level: "error"
    port: 5000
    models:
      connection: 'testLocalDiskDb'
    hooks:
      grunt: false
    , done

after (done) ->
  try
    fs.unlinkSync '../../.tmp/testLocalDiskDb.db' # temp db to be deleted
  catch error
    console.log 'DB not yet created therefore - not deleted'
  app.lower done 

-----------------------------
-----------------------------
# tests/test_example.coffee
request = require 'supertest'
fs = require 'fs'
should = require('chai').should()

describe 'when lifting Server', (done) ->
  it 'should respond with a 200 response code', (done) ->
    # basic test of api
    request(app.ws.server)
    .get('/')
    .set('Content-Type', 'application/json')
    .end (err, res) ->
      should.exist(res.status)
      res.status.should.equal 200
      done()
Reply all
Reply to author
Forward
0 new messages