我想同时运行我的 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();
});
似乎值得指出,在一个开玩笑的问题中也有关于这个的讨论: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;
});
在使用 Playwright 进行浏览器测试时遇到同样的问题,其中一个测试套件只需要一个浏览器实例。必须用
setInterval
的 Promise 来包装它。在您的情况下,它应该如下所示:
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);
});
}
所以你只需要分配适当的支票
interval
和timeout
这应该足够长让你的数据asycn
打电话回来。