I want to run a function
/ task
whenever any jest
test fails. Instead of wrapping all of my test's with try
/ catch
or add an if
check, is there a way I can utilize the afterEach
?
If the test fails then I want it to fail, just run a separate function.
For example:
test('nav loads correctly', async () => {
const listItems = await page.$$('[data-testid="navBarLi"]')
expect(listItems.length).toBe(4)
if (listItems.length !== 4)
await page.screenshot({path: 'screenshot.png'})
})
This is adding an if check... But I want something more robust for all of my tests.
I want to run a function
/ task
whenever any jest
test fails. Instead of wrapping all of my test's with try
/ catch
or add an if
check, is there a way I can utilize the afterEach
?
If the test fails then I want it to fail, just run a separate function.
For example:
test('nav loads correctly', async () => {
const listItems = await page.$$('[data-testid="navBarLi"]')
expect(listItems.length).toBe(4)
if (listItems.length !== 4)
await page.screenshot({path: 'screenshot.png'})
})
This is adding an if check... But I want something more robust for all of my tests.
Share Improve this question edited May 12, 2019 at 19:26 Towkir 4,0142 gold badges26 silver badges42 bronze badges asked Jan 22, 2018 at 18:39 Tyler ClarkTyler Clark 1911 silver badge3 bronze badges 5- What will be the purpose of this function? will it log the failure? – Oro Commented Jan 22, 2018 at 19:05
- 3 basically I want to take a screenshot when a test fails.. (I'm using google's puppeteer). AfterEach would work if it had access to the current test. To check if it passes or fails. But looks like this is not built in github./facebook/jest/issues/5292 – Tyler Clark Commented Jan 22, 2018 at 19:25
- 4 The other option I could think of, is implementing a reporter (in addition to the default one). – Oro Commented Jan 22, 2018 at 19:36
- there is discussion in github./smooth-code/jest-puppeteer/issues/43 with some workarounds. Also jest-screenshot-reporter sounds like exactly what you need – skyboyer Commented Oct 21, 2018 at 7:41
- Possible duplicate of Check if test failed in afterEach of Jest – A Jar of Clay Commented May 20, 2019 at 10:53
3 Answers
Reset to default 5@Tyler Clark I haven't attempted this with afterEach
, but I suspect you could apply something similar this my SO answer here. (pasting a version of it below for context - altered to work with afterEach
)
const GLOBAL_STATE = Symbol.for('$$jest-matchers-object');
describe('Describe test', () => {
afterEach(() => {
if (global[GLOBAL_STATE].state.snapshotState.matched !== 1) {
console.log(`\x1b[31mWARNING!!! Catch snapshot failure here and print some message about it...`);
}
});
it('should test something', () => {
expect({}).toMatchSnapshot(); // replace {} with whatever you're trying to test
});
});
Store current spec results in Jasmine and access it in afterEach
.
Add a custom Jasmine reporter for
specStarted
and store the spec results tojasmine.currentTest
.jasmine.getEnv().addReporter( { specStarted: result => jasmine.currentTest = result } );
The unintuitive thing about this is that even though we're storing this in
specStarted
before the results are in,jasmine.currentTest
stores a reference to theresult
object which will get updated dynamically as the spec runs so when we access it in ourafterEach
, it will be holding the results of the spec properly.Check for
failedExpectations
in yourafterEach
and take a screenshot if there's been any failures.afterEach( async () => { if ( jasmine.currentTest.failedExpectations.length > 0 ) { // There has been a failure. await driver.takeScreenshot(); // Or whatever else you want to do when a failure occurs. } } );
Why not use try/catch?
If you don't like how it looks, you can hide the ugliness away in a function:
function runAssertion(assertion, onFailure) {
try {
assertion();
} catch (exception) {
onFailure();
throw exception;
}
}
Then call it like so:
test('nav loads correctly', async () => {
const listItems = await page.$$('[data-testid="navBarLi"]')
runAssertion(
() => { expect(listItems.length).toBe(4) },
() => { await page.screenshot({path: 'screenshot.png'}) }
)
})
This is the approach our team has taken to avoid using try/catch everywhere.