我们使用 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
and beforeEach
? - 如果使用以下命令执行上述测试,则有效--runInBand
选项,其中“...在当前进程中串行运行所有测试...”
但当并行执行时,它开始随机失败,主要是指tenantId
未定义。鉴于这些测试是 ~200 个类似测试的一部分,因此全部都通过了。同时,这取决于机器。具有 8 核/16 线程的构建代理只有 50-60% 通过测试。我使用四核 CPU 的同事大约有 80% 通过了测试,而对于使用双核 CPU 的我来说,有时只有 1-2 个测试失败,其他时候大约有 10 个测试失败。显然这取决于并行度。
我发现了 2 个 GitHub 问题,人们提到了使用的可能性this
共享上下文(不再起作用)或将所有内容封装在describe
:
- https://github.com/facebook/jest/issues/3553 https://github.com/facebook/jest/issues/3553
- https://github.com/facebook/jest/issues/3673 https://github.com/facebook/jest/issues/3673
所以我尝试了一个非常幼稚的方法:
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
});
});
但这似乎并没有任何效果。
我真的很想并行运行测试,但我在文档中找不到任何相关内容。也许我不知道我应该寻找什么?