mocha icon indicating copy to clipboard operation
mocha copied to clipboard

Should timing badges take into account beforeEach/afterEach?

Open joliss opened this issue 12 years ago • 23 comments

My beforeEach functions are pretty slow, and sometimes even dominate test time. (I set up test fixture data and initialize an Ember app.) But the little timing badges that show up in the browser (above 50ms or so) do not include this time, they only seem to measure the time of the test functions themselves.

I'm thinking that it would be sensible for the badges to include the beforeEach/afterEach time.

(Perhaps there are also other parts where these timings are used, like timeouts -- I'm fairly new to mocha.)

What do you think?

joliss avatar May 09 '12 23:05 joliss

hmm tough call, maybe as a flag or something, I wouldn't want to see them all the time personally but yeah I see what you're saying

tj avatar May 09 '12 23:05 tj

I was just about to file a bug about this.

[snip]

✔ 268 tests complete (1116ms)

make test 0.96s user 0.11s system 8% cpu 13.048 total


Personally I think the beforeEach/etc.. timing details are more important then the assertions. Typically I put the most time intensive stuff in my beforeEach (setting up the fixture, dom, whatever) and then run my assertions against that which takes virtually no time by comparison.

lightsofapollo avatar May 17 '12 00:05 lightsofapollo

+1

domenic avatar May 17 '12 01:05 domenic

You could just setup a helper function that does all your setup, and then call it inside your test. This way, you explicitely test your setup, and it would be included in the time measurements.

emilecantin avatar Jun 05 '12 14:06 emilecantin

+1 from me

@emilecantin: well, that makes the beforeEach function obsolete ;)

andreasgerstmayr avatar Jun 10 '12 15:06 andreasgerstmayr

@andihit: Not really, before / beforeEach is for setup that is outside of the scope of your test case. It aims to provide an environment in which you can then run your test. If your setup is relevant to the success / failure / performance of your test, then it belongs IN the test...

emilecantin avatar Jun 10 '12 15:06 emilecantin

If your setup is relevant to the success / failure / performance of your test, then it belongs IN the test...

In what case is the setup not relevant for the success/failure of the test?

Typically I put the most time intensive stuff in my beforeEach (setting up the fixture, dom, whatever) and then run my assertions against that which takes virtually no time by comparison.

Same here ;)

andreasgerstmayr avatar Jun 10 '12 16:06 andreasgerstmayr

In what case is the setup not relevant for the success/failure of the test?

For example, when I am testing an object's methods, the instantiation of said object is not relevant; it's not what I test. Instantiation is part of another, unrelated test.

emilecantin avatar Jun 10 '12 16:06 emilecantin

Technically it is relevant that your object is initialized when you test methods of it. But I get what you mean, it's not what you test in a particular test.

Maybe we want a second badge of each test which shows the duration of the beforeEach (and afterEach)? Or show detailed information on hover (before, beforeEach, test, afterEach, after durations)?

andreasgerstmayr avatar Jun 10 '12 16:06 andreasgerstmayr

I think detailed information on hover would be a nice addition. While I don't think beforeEach / afterEach timings shouldn't be included in the test's timings, there's no reason to not measure it. On the command line, we could add a '--detailed' flag, or an alternate reporter.

emilecantin avatar Jun 10 '12 17:06 emilecantin

@emilecantin yeah i agree, i think a reporter would be the cleanest route, dot and some of the others wouldn't really work, or maybe just a --verbose variant of spec and list

tj avatar Jun 10 '12 17:06 tj

+1 If not included in test timing, just a separate timing log for the before/after functions.

jaketrent avatar Jan 11 '13 15:01 jaketrent

in #700 this was brought up again, I think for now maybe aggregating them would be safest. This gets a little tricky since multiple beforEach's can be used even at the same level so describing them in the output would be very verbose unless it's opt-in

tj avatar Jan 11 '13 16:01 tj

Looks like this was never completed:

$ cat example.js
beforeEach(function(done) {
  setTimeout(done, 180);
});

it('foo', function(done) {
  setTimeout(done, 100);
});

it('bar', function(done) {
  done();
});

$ ./bin/mocha --reporter spec example.js

  ✓ foo (101ms)
  ✓ bar

  2 passing (468ms)

I could come up with a PR for this. The resulting output would be:

$ ./bin/mocha --reporter spec example.js

  ✓ foo (281ms)
  ✓ bar (181ms)

  2 passing (468ms)

$ ./bin/mocha --reporter --verbose spec example.js

    beforeEach (181ms)
  ✓ foo (281ms)
    beforeEach (181ms)
  ✓ bar (181ms)

  2 passing (468ms)

To clarify, I'd probably keep the current behavior of having timeouts apply to runnables, and not aggregated test execution time.

danielstjules avatar Mar 08 '15 22:03 danielstjules

@danielstjules It would be also be nice to show the name of the hook, for when you have multiple ones.

dasilvacontin avatar Apr 03 '15 10:04 dasilvacontin

@danielstjules go for it! :)

jbnicolai avatar Jun 07 '15 01:06 jbnicolai

@danielstjules would love this!

kevinburkeshyp avatar Aug 25 '15 04:08 kevinburkeshyp

cc @Nokel81; you might want to consider this when looking at the stats gathering.

boneskull avatar Mar 08 '18 05:03 boneskull

Great idea, the aggregater should have access to this information so reporters will be able to start using it

Nokel81 avatar Mar 08 '18 11:03 Nokel81

@boneskull @Nokel81 I created a PR https://github.com/mochajs/mocha/pull/3776 (based on https://github.com/mochajs/mocha/pull/2244) which introduces an option --time-setup to include the duration of beforeEach hooks in the duration of each test. I have found this useful for optimizing tests in my own projects.

sgilroy avatar Feb 26 '19 03:02 sgilroy

bump, seeing that the pr is still open, is it still being worked on? what are the alternatives?

jsphkm avatar Aug 18 '19 15:08 jsphkm

Would be awesome to get #3776 merged, it's exactly the solution I need. My use case is CircleCI test splitting which uses the timing data from the junit reporter, which is completely off if it doesn't include beforeEach.

theflow avatar Nov 01 '19 09:11 theflow

I ran into this and was sadden to see that the PR #3776 is still outstanding, so I set out to see if there was some way I could hack this behaviour into current MochaJS, and this is what I came up with:

let start = performance.now()
export const mochaHooks = {
    beforeEach: async function () {
        const currentTest = this.currentTest
        const originalRun = currentTest.run
        currentTest.run = function (fn) {
            originalRun.call(currentTest, function (...args) {
                const end = performance.now()
                currentTest.duration = Math.round(end - start)
                start = end
                fn(...args)
            })
        }
    }
}

It's put into a --require file which adds a global hook.

I have made it such that start is set immediately and updated after each test, this ensures all time spent between tests are included, so any before / beforeEach / after / afterEach etc. is counted in the duration.

It's kind of hackish, but works.

micdah avatar Aug 30 '21 10:08 micdah