You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用beforeEach修改test.each测试数据的问题及解决方法

问题描述

为了针对多个测试条件验证多个数据文件,编写了如下简化代码:

describe.each([ ['Data 1', 'd1'], ['Data 2', 'd2']])('Test group using %s with tag %s', (datafile, tag) => 
  {
  let groupData = [{'id':10},{'id':20}];
  let groupTag = '';
  beforeEach(() => {
    groupTag = tag;
    console.log('Beginning tests for '+tag+' using '+datafile);
    if(tag == 'd1') groupData = [{'id':30},{'id':40}];
    if(tag == 'd2') groupData = [{'id':50},{'id':60}];
    console.log(JSON.stringify(groupData[0]));
  });
  test.each(groupData)('Test case $# [tag:sandbox]', row =>  {
     console.log(groupTag+' - Running test '+row.id); 
     expect(row.id).toBeDefined(); //example test
    });
  });

控制台输出如下(已添加注释):

- Beginning tests for d1 using Data 1
 - {"id":30}
 - d1 - Running test 10 **should be 30** 
 - Beginning tests for d1 using Data 1 
 - {"id":30} 
 - d1 - Running test 20 **should be 40** 
 - Beginning tests for d2 using Data 2
 - {"id":50}
 - d2 - Running test 10 **should be 50** 
 - Beginning tests for d2 using Data 2 
 - {"id":50} 
 - d2 - Running test 20 **should be 60**

问题分为两部分:

  1. 我期望用beforeEach重置test.each的数据表是否有误(即该数据表在运行时是不可变的)?
  2. 如何实现我想要的测试效果?

问题解答

问题1解答

没错,你的理解是对的。test.each的参数是在测试定义阶段就被解析并固定下来的,而beforeEach是在测试执行阶段才运行的。也就是说,当test.each(groupData)被声明时,groupData还是初始的[{'id':10},{'id':20}],后续beforeEach里对groupData的修改完全不会影响到test.each已经生成的测试用例,这就是为什么输出里的id还是初始值的原因。

问题2解答

要实现根据不同tag动态切换测试数据的效果,有两种实用方案:

方案1:提前在describe.each内部生成对应测试数据

把groupData的生成逻辑提前到describe.each的回调中,不需要依赖beforeEach,直接在定义test.each时就使用对应tag的数据:

describe.each([['Data 1', 'd1'], ['Data 2', 'd2']])('Test group using %s with tag %s', (datafile, tag) => {
  // 直接根据tag生成对应测试数据
  const groupData = tag === 'd1' ? [{'id':30},{'id':40}] : [{'id':50},{'id':60}];
  let groupTag = '';

  beforeEach(() => {
    groupTag = tag;
    console.log('Beginning tests for '+tag+' using '+datafile);
    console.log(JSON.stringify(groupData[0]));
  });

  test.each(groupData)('Test case $# [tag:sandbox]', row => {
    console.log(groupTag+' - Running test '+row.id); 
    expect(row.id).toBeDefined(); // example test
  });
});

方案2:用函数延迟获取测试数据

如果测试数据需要在beforeEach中做更复杂的初始化(比如异步加载文件),可以把test.each的参数改成一个函数,让它在测试执行阶段才去获取最新数据:

describe.each([['Data 1', 'd1'], ['Data 2', 'd2']])('Test group using %s with tag %s', (datafile, tag) => {
  let groupData = [{'id':10},{'id':20}];
  let groupTag = '';

  beforeEach(() => {
    groupTag = tag;
    console.log('Beginning tests for '+tag+' using '+datafile);
    if(tag == 'd1') groupData = [{'id':30},{'id':40}];
    if(tag == 'd2') groupData = [{'id':50},{'id':60}];
    console.log(JSON.stringify(groupData[0]));
  });

  // 用函数延迟获取数据,确保执行阶段拿到最新的groupData
  test.each(() => groupData)('Test case $# [tag:sandbox]', row => {
    console.log(groupTag+' - Running test '+row.id); 
    expect(row.id).toBeDefined(); // example test
  });
});

修改后控制台输出会符合预期:

- Beginning tests for d1 using Data 1
- {"id":30}
- d1 - Running test 30
- Beginning tests for d1 using Data 1 
- {"id":30} 
- d1 - Running test 40 
- Beginning tests for d2 using Data 2
- {"id":50}
- d2 - Running test 50 
- Beginning tests for d2 using Data 2 
- {"id":50} 
- d2 - Running test 60

内容的提问来源于stack exchange,提问作者Simon Oliver

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 12:55:16