最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to run function when any test fails - Jest - Stack Overflow

programmeradmin6浏览0评论

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
Add a ment  | 

3 Answers 3

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.

  1. Add a custom Jasmine reporter for specStarted and store the spec results to jasmine.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 the result object which will get updated dynamically as the spec runs so when we access it in our afterEach, it will be holding the results of the spec properly.

  2. Check for failedExpectations in your afterEach 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.

发布评论

评论列表(0)

  1. 暂无评论