Jon
Jon

Reputation: 8531

Get Jest test name within beforeEach() and afterEach()

I am running Jest and am trying to log the start and end timestamp for each of my tests. I am trying to stick my timestamp logging inside the beforeEach() and afterEach() blocks. How would I log the name of my Jest test within the beforeEach() and afterEach() block?

Also, is there a more global way of logging test name and timestamp before and after all the tests without using beforeEach() and afterEach()?

Upvotes: 12

Views: 6409

Answers (3)

sqwk
sqwk

Reputation: 2699

You can set up a test environment and either log times directly or write the name and timing info into a global variable that is only available inside the tests in question:

./tests/testEnvironment.js

const NodeEnvironment = require('jest-environment-node');

class TestEnvironment extends NodeEnvironment {
    constructor(config, context) {
        super(config, context);
    }

    async setup() {
        await super.setup();
    }

    async teardown() {
        await super.teardown();
    }

    async handleTestEvent(event, state) {
        if (event.name === 'test_start') {
            // Log things when the test starts
        } else if (event.name === 'test_done') {
            console.log(event.test.name);
            console.log(event.test.startedAt);
            console.log(event.test.duration);
            this.global.someVar = 'set up vars that are available as globals inside the tests';
        }
    }

}

module.exports = TestEnvironment;

For each test suite the following comment is needed to use this environment:

/**
 * @jest-environment ./tests/testEnvironment
 */

Also see https://jestjs.io/docs/configuration#testenvironment-string

Upvotes: 0

Ilmarinen123
Ilmarinen123

Reputation: 586

You can access the name of the current test in jest like this:

expect.getState().currentTestName

This method also works inside beforeEach / afterEach

The only downside is that it will also contain the name of your current describe section. (which may be fine depending on what you are trying to do.

Also it does not give you the timing information that you asked for.

Upvotes: 22

Estus Flask
Estus Flask

Reputation: 222989

The information on currently running test is unavailable in beforeEach. Similarly to Jasmine, suite object is available in Jest as this context in describe function, it's possible to patch spec definitions to expose needed data. A more trivial way would be to define custom wrapper function for global it that intercepts test name.

Custom reporter is a better way to do this. Reporter interface is self-documented, necessary data is available in testResult.

Performance measurements are already available:

module.exports = class TimeReporter {
  onTestResult(test, testResult, aggregatedResult) {
    for (let { title, duration } of testResult.testResults)
        console.log(`test '${title}': ${duration} ms`);
  }
}

Can be used like:

reporters: ['default', "<rootDir>/time-reporter.js"]

As it was noted, there are beforeAll and afterAll, they run once per describe test group.

Upvotes: 3

Related Questions