如何在任何测试失败时运行函数-Jest

18

我希望在任何 jest 测试失败时运行一个 function / task 。 有没有办法利用 afterEach 而不是用 try / catch 包装所有测试或添加一个 if 检查?

如果测试失败,则我希望它失败,只需运行一个单独的函数。

例如:

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'})

  })

这里添加一个if检查...但我希望对于所有测试都有更强大的东西。


这个函数的目的是什么?它会记录失败吗? - Or B
3
基本上,我希望在测试失败时拍摄屏幕截图(我使用的是Google的Puppeteer)。如果AfterEach有当前测试的访问权限,则会起作用,以检查它是否通过或失败。但看起来这并不是内置的,详情请参见https://github.com/facebook/jest/issues/5292。 - Tyler Clark
4
我能想到的另一个选项是实现一个报告器(除了默认的报告器)。 - Or B
在 https://github.com/smooth-code/jest-puppeteer/issues/43 中有一些解决方法的讨论。此外,jest-screenshot-reporter 看起来正是你所需要的。 - skyboyer
可能是 Jest 的 afterEach 中检查测试是否失败 的重复问题。 - A Jar of Clay
3个回答

4

@Tyler Clark 我没有尝试过使用afterEach,但我认为您可以将类似的东西应用于我在这里发表的SO答案。(以下是上下文中的版本 - 经过修改以适用于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
  });
});

2

将当前的 Jasmine 测试结果存储并在 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.
      }
    } );
    

0

为什么不使用 try/catch 呢?

如果你不喜欢它的外观,可以将其封装在一个函数中以隐藏其丑陋:

function runAssertion(assertion, onFailure) {
    try {
        assertion();
    } catch (exception) {
        onFailure();
        throw exception;
    }
}

然后这样调用:

test('nav loads correctly', async () => {
    const listItems = await page.$$('[data-testid="navBarLi"]')

    runAssertion(
        () => { expect(listItems.length).toBe(4) },
        () => { await page.screenshot({path: 'screenshot.png'}) }
    )
})

这是我们团队采取的方法,以避免在各个地方使用try/catch。


1
在使用 toMatchSnapshot 时似乎无法正常工作。 - Jeremy
@Jeremy 抱歉,我从未使用过 toMatchSnapshot。当它失败时不能抛出异常。 - byxor
2
就是这样 - 请参考这个Github问题。我的这篇Stack Overflow答案提供了一个解决方案。 - Jeremy
1
你不应该写一个方法来获取测试运行器的测试状态...这只是一个权宜之计,但在我看来仍然有点粗糙。 - zmorris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接