Make test name available in beforeEach()
and afterEach()
.
When running Selenium tests it's helpful to take a screenshot after every test. Best name for those files would be the test name. Now I use url and timestamp, which are not that good.
For further logging purposes beforeEach()
could use the test name too, to log when that test starts. It makes easier to search server logs from the same time.
afterEach(async (testName) => {
await saveScreenshot(testName);
log(`Test '${testName}' ended at ${getTime()}`);
});
Interesting suggestion, thanks! If this is implemented, the argument should probably be an object literal to make it easy to pass in more things to the function without a breaking change.
Sounds cool. This will be possible once we get rid of done
and replace it with generic purpose object, like AVA does :)
That won't happen any time soon though - in the meantime you can use jest-image-snapshot
- the snapshot file will get the test's name automatically. If that doesn't fit, I'd look into implementing it in some other way using jest's snapshot features so that you get the name included
just wanted to add that this would be super useful when using an XHR vcr like nock back. Right now I have to do this in each test
const { nockDone } = await nockBack('fixtureName.json')
// the actual test
nockDone()
it would be awesome to just do something like
let nockDone
beforeEach(() => {
const result = await nockBack(testName + '.json')
nockDone = result.nockDone
})
afterEach(() => {
nockDone()
})
in case this is helpful, mocha keeps a whole suite of helpers in the befores' this
scope. Would it make sense to pass some sort of class instance, instead of an object literal, so we can pave the way for things like .skip()
programmatically?
https://mochajs.org/api/suite#fullTitle
```js
describe('test suite', () => {
beforeEach(function () {
console.log(this.currentTest.fullTitle())
// test suite nested names are included too
}
describe('nested names are', () => {
it('included too', () => {
})
})
})
My current solution.
File: jest.config.js
:
module.exports = {
setupFilesAfterEnv: ['./jest.setup.js'],
.................
};
File jest.setup.js
:
// Patch tests
jasmine.getEnv().addReporter({
specStarted: result => jasmine.currentTest = result,
specDone: result => jasmine.currentTest = result,
});
File any-test.spec.ts
describe('Test description', () => {
beforeEach(() => console.log('Before test', jasmine['currentTest'].fullName));
afterEach(() => console.log(
'Test',
jasmine['currentTest'].fullName,
'failed',
!!jasmine['currentTest'].failedExpectations.length
));
it('example', () => expect(1).toBe(1));
});
I hope it helps somebody.
This would be handy simply because I'm using jest to run long integration tests with lots of logging. It's nice to see which test is being run before the setup in the before* hooks start.
@optimistex 's solution still works today, so that's nice. Here's the types, so you don't have to do the ['currentTest']
and force it into an any
type:
declare namespace jasmine {
const currentTest: {
id: string;
description: string;
fullName: string;
failedExpectations: {
actual: string;
error: Error;
expected: string;
matcherName: string;
message: string;
passed: boolean;
stack: string;
}[];
passedExpectations: unknown[];
pendingReason: string;
testPath: string;
};
}
Note I made passedExpectations
an unkown[]
, as it was always an empty array for me. Not sure if it ever contains something.
Just a quick note: The last bits of Jasmine remaining in Jest are supposed to be phased out soon, as jest-circus
becomes the default test runner implementation. This does not mean using Jasmine-specific APIs will no longer be possible, just that you may miss out on any new features / fixes specific to jest-circus
. See https://jestjs.io/blog/2020/05/05/jest-26 for a timeline.
In jest-circus, I noticed that when I console.log the event.test
inside handleTestEvent
, I get a recursive test type (something like test -> parent -> parent -> ROOT_DESCRIBE_BLOCK):
console.log({
type: 'test',
asyncError: "ErrorWithStack: etc...",
duration: null,
errors: [],
fn: [Function (anonymous)],
invocations: 1,
mode: undefined,
name: 'first it',
parent: {
type: 'describeBlock',
children: [ [Circular *1], [Object] ],
hooks: [],
mode: undefined,
name: 'first describe',
parent: {
type: 'describeBlock',
children: [Array],
hooks: [Array],
mode: undefined,
name: 'ROOT_DESCRIBE_BLOCK',
parent: undefined,
tests: []
},
tests: [ [Circular *1] ]
},
startedAt: 1591598218051,
status: null,
timeout: undefined
})
I was wondering if there is an equivalent function to jasmine['currentTest'].fullName
?
EDIT: In the meantime this is what I did to get the full test name:
if (event.name === "test_start") {
let testNames = [];
let currentTest = event.test;
while (currentTest) {
testNames.push(currentTest.name);
currentTest = currentTest.parent;
}
this.global.testName = testNames
.slice(0, testNames.length - 1)
.reverse()
.map((name) => name.replace(/\W/g, "-"))
.join("-");
}
Bumping this if there is any clear update or expectation on this feature.
I stumbled across the following which may be of interest to others.
beforeEach(() => {
console.log(expect.getState().currentTestName);
})
afterEach(() => {
console.log(expect.getState().currentTestName);
})
I stumbled across the following which may be of interest to others.
beforeEach(() => { console.log(expect.getState().currentTestName); }) afterEach(() => { console.log(expect.getState().currentTestName); })
Very nice, It works on [email protected]. Thanks!
Most helpful comment
My current solution.
File:
jest.config.js
:File
jest.setup.js
:File
any-test.spec.ts
I hope it helps somebody.