【发布时间】:2020-06-13 01:16:37
【问题描述】:
我们使用 jest 来测试我们的 API,并且有相当复杂的场景。我们使用beforeAll 函数为每个测试设置通用帮助变量,有时设置租户分离,在其他情况下,我们使用beforeEach 函数为测试设置租户分离,并为测试设置一些默认配置租户,...
例如,测试可能像这样(如您所见,我们使用 TypeScript 来编写测试,以防万一):
let apiClient: ApiClient;
let tenantId: string;
beforeAll(async () => {
apiClient = await getClientWithCredentials();
});
beforeEach(async () => {
tenantId = await createNewTestTenant();
});
describe('describing complex test scenario', () => {
it('should have some initial state', async () => {
await checkState(tenantId);
});
it('should have some state after performing op1', async () =>{
await op1(tenantId);
await checkStateAfterOp1(tenantId);
});
it('should have some state after performing op2', async () =>{
await op2(tenantId);
await checkStateAfterOp2(tenantId);
});
it('should have some state after performing op1 and op2', async () =>{
await op1(tenantId);
await op2(tenantId);
await checkStateAfterOp1AndOp2(tenantId);
});
it('the order of op1 and op2 should not matter', async () =>{
await op2(tenantId);
await op1(tenantId);
await checkStateAfterOp1AndOp2(tenantId);
});
});
describe('another similar complex scenario', () => {
// ... you see where this is going
});
问题是,共享由beforeAll 和beforeEach 初始化的变量的最佳方式是什么? - 如果使用--runInBand 选项执行上述测试,"... 在当前进程中连续运行所有测试..."
但是当并行执行时,它开始非常随机地失败,主要是指tenantId 未定义。鉴于这些测试是大约 200 个类似测试的一部分,因此全部通过。同时,它取决于机器。具有 8 核 / 16 线程的构建代理只有 50-60% 通过测试。我的四核 CPU 同事通过了约 80% 的测试,而对我来说,双核 CPU 有时只有 1-2 次测试失败,其他时候约 10 次。所以显然这取决于并行度。
我发现了 2 个 GitHub 问题,人们提到可以使用 this 共享上下文(不再起作用)或将所有内容封装在 describe 中:
所以我尝试了一个非常幼稚的方法:
describe('tests', () => {
let apiClient: ApiClient;
let tenantId: string;
beforeAll(async () => {
apiClient = await getClientWithCredentials();
});
beforeEach(async () => {
tenantId = await createNewTestTenant();
});
describe('describing complex test scenario', () => {
it('should have some initial state', async () => {
await checkState(tenantId);
});
it('should have some state after performing op1', async () =>{
await op1(tenantId);
await checkStateAfterOp1(tenantId);
});
it('should have some state after performing op2', async () =>{
await op2(tenantId);
await checkStateAfterOp2(tenantId);
});
it('should have some state after performing op1 and op2', async () =>{
await op1(tenantId);
await op2(tenantId);
await checkStateAfterOp1AndOp2(tenantId);
});
it('the order of op1 and op2 should not matter', async () =>{
await op2(tenantId);
await op1(tenantId);
await checkStateAfterOp1AndOp2(tenantId);
});
});
describe('another similar complex scenario', () => {
// ... you see where this is going
});
});
但这似乎没有任何效果。 我真的很想并行运行测试,但我在文档中找不到任何相关内容。也许我不知道我应该寻找什么?
【问题讨论】:
-
我只是偶然发现了完全相同的问题/问题?这段时间你发现了吗?
-
@Vetterjack 我不知道发生了什么变化,也许是新版本的 jest 出现了,或者我们在其他地方遇到了错误,但我的问题中描述的方法现在似乎对我们有用。在过去的 4 个月里,我们正在同时对 32 名工作人员进行测试,并且没有遇到任何奇怪的问题,唯一的解释是数据混淆了,所以我猜它正在工作
-
谢谢!我会试试看。顺便提一句。你现在用的是哪个版本的?
-
@Vetterjack
23.6.0 -
我不清楚你说的分享是什么意思?您遇到的问题不是基于tenandId 确实被所有可能同时运行的测试共享的事实吗?您不想在每个测试中初始化
const tenantId = await createNewTestTenant();吗?
标签: typescript async-await jestjs web-api-testing