如何在Jest中运行并发测试,每个请求有多个测试?

时间:2017-03-06 19:07:34

标签: jestjs

我想同时运行我的Jest测试,但我遇到了一个问题:

我在端点上测试结果,我想测试一下它的多个内容。所以在我的beforeAll函数中,我发出请求并存储响应,然后在多个测试中测试响应。这可以同步工作,但是当我同时进行测试时,它不再允许你将变量传递给测试,所以它不行。或者,我可以将请求放在测试本身中,然后期待很多关于响应的事情,但是如果出现问题,我就不会有粒度来看看出了什么问题。

这种情况有没有解决方案?

这有效:

let data;
beforeAll(async () => {
    data = await getDataFromRequest();
}
it('value1 should be truthy', () => {
    expect(data.value1).toBeTruthy();
}
it('value2 should be truthy', () => {
    expect(data.value2).toBeTruthy();
}

这也有效:

it.concurrent('data should have correct values', async () => {
    const data = await getDataFromRequest();
    expect(data.value1).toBeTruthy();
    expect(data.value2).toBeTruthy();
}

但我想要的是:

let data;
beforeAll(async () => {
    data = await getDataFromRequest();
}
it.concurrent('value1 should be truthy', () => {
    expect(data.value1).toBeTruthy();
}
it.concurrent('value2 should be truthy', () => {
    expect(data.value2).toBeTruthy();
}

2 个答案:

答案 0 :(得分:1)

似乎值得指出,在一个开玩笑的问题中也有关于此问题的讨论:https://github.com/facebook/jest/issues/4281

它的要点:它不会那样工作而且没有计划。可能的解决方法:

const dataPromise = getSomeDataPromise();

test.concurrent('one', async () => {
  const data = await dataPromise;
});

test.concurrent('two', async () => {
  const data = await dataPromise;
});

答案 1 :(得分:0)

使用Playwright进行浏览器测试时会遇到相同的问题,其中一个测试套件仅需要一个浏览器实例。必须用setInterval来包装它。在您的情况下,应如下所示:

let data;

beforeAll(async () => {
    data = await getDataFromRequest();
}
test.concurrent('value1 should be truthy', async () => {
    await waitForData();
    expect(data.value1).toBeTruthy();
}
test.concurrent('value2 should be truthy', async () => {
    await waitForData();
    expect(data.value2).toBeTruthy();
}

/**
 * @param {number} interval -  the interval to check data availability
 * @param {number} timeout -  the overall timeout value
 * @return Promise of your data OR reject if timeout.
 */
function waitForData(interval = 500, timeout = 5000){
  let acc = 0; // time accumulation
  return new Promise((resolve, reject) => {
    const i = setInterval(() => {
      acc += interval;
      if (data) {
        clearInterval(i);
        resolve(data);
      }
      if (acc > timeout) {
        clearInterval(i);
        reject();
      }
    }, interval);
  });
}

因此,您只需要分配适当的支票intervaltimeout,这些支票应该足够长,以便您的数据asycn调用返回。