【问题标题】:Can Jest's beforeAll wait until its describe scope to execute?Jest 的 beforeAll 可以等到它的描述范围执行吗?
【发布时间】:2020-10-14 12:40:25
【问题描述】:

过去几天我一直对 Jest 如何在 describe 块中处理 beforeAll 感到困惑。我希望每个describebeforeAll 仅在需要在describe 中运行测试时才执行。

我已经编写了这个测试文件(测试测试文件?):

async function wait1sec() {
  return new Promise(resolve => setTimeout(resolve, 1000));
}

async function logWait(i, isDescribe = false) {
  console.log(`before wait inside ${ isDescribe ? 'describe' : 'it' } #` + i);
  await wait1sec();
  console.log(`after wait inside ${ isDescribe ? 'describe' : 'it' } #` + i);
  expect(true).toEqual(true);
}

function logSync(i, isBefore = false) {
  console.log(`synchronous function ${ isBefore ? 'before' : 'it' } #${ i }`);
}

describe('async behavior', () => {
  describe('block 1', () => {
    const i = 1;
    beforeAll(() => logSync(i, true));
    it('sync test in block 1', () => logSync(i));
  });
  
  describe('block 2', () => {
    const i = 2;
    beforeAll(() => logSync(i, true));
    it('sync test in block 1', () => logSync(i));
  });

});

您可以看到我在异步行为的上下文中对此进行测试这一事实的残余,但事实证明即使没有异步它也会令人困惑。

我希望得到的是:

synchronous function before #1
synchronous function it #1
synchronous function before #2
synchronous function it #2

我真正得到的是

synchronous function before #1
synchronous function before #2
synchronous function it #1
synchronous function it #2

更糟糕的是,如果我跳过第二个块(带有xdescribe),第二个beforeAll 仍然运行!

所以我想它并没有那么令人困惑,我想它是如何工作的很清楚,但这不是我想要的工作方式。

除了简单地将我的“beforeAll”代码放在我对块的第一个测试中之外,有什么方法可以得到我想要的结果?


注意:对于一些上下文,我正在使用这些测试与外部 REST API 进行交互,以测试我是如何设置工作流的。换句话说,我不是在测试我自己的代码,与服务器的所有交互都是真实的,并且会产生真实的 CRUD 事务。它们并不重要,而且很容易清理,所以这是一件安全且可控的事情。我的测试建立在彼此的基础上,从一个describe 到下一个(即,我正在使用的页面在第一次测试之前创建一次,并在其余部分使用 REST API 进行修改),这意味着beforeAlldescribe #2 在describe #1 的测试之前运行可能会搞砸整个事情。 (特别是如果我尝试使用 xdescribe 跳过块!)

【问题讨论】:

  • 通常不鼓励这种有状态的集成测试,因此这是框架未涵盖的边缘情况。我不确定它是否已记录在案,但这是可以预料的。 beforeAll 和 beforeEach 保证在测试之前运行并且他们这样做。此外,如果它们失败了,即使使用bail,测试也不会停止,这是已知的 Jest 陷阱之一,可能也不适合您的情况。对于您想要做的事情,只需将另一个 it 添加到执行设置的开头,并确保为有状态测试启用 bail
  • 似乎即使在“正确”(无状态)测试环境中,仅在其块执行之前运行的beforeAll 也不会是边缘情况?我想我一定是错的。
  • 我只想指出 beforeEach 仅适用于在其定义的同一 describe 范围内定义的测试。也许这就是您正在寻找的功能?

标签: jestjs


【解决方案1】:

您可以使用-i flag 按顺序运行您的测试;
您也可以将您的描述块包装到 IIFE 中(或为此添加函数):

describe('async behavior', () => {
  (() =>
    describe('block 1', () => {
      ...
    }))();

  (() =>
    describe('block 2', () => {
      ...
    }))();
});

它会按您的预期工作,但我不确定这是一个好习惯。也许这种方式会为其他一些异步行为产生一些其他逻辑错误;

【讨论】:

    猜你喜欢
    • 2012-07-18
    • 2019-06-21
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    相关资源
    最近更新 更多