admin管理员组

文章数量:1366902

In order that I can test multiple data files against multiple criteria, I have some (distilled) code that looks like this:

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
    });
  });

The console.log output is like this (with my comments added):

 - 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**

So my question is twofold:

  1. Is my expectation that beforeEach can be used to reset the test.each data table incorrect (i.e. the table is invariant at runtime)?
  2. How can I achieve the result I am looking for?

In order that I can test multiple data files against multiple criteria, I have some (distilled) code that looks like this:

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
    });
  });

The console.log output is like this (with my comments added):

 - 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**

So my question is twofold:

  1. Is my expectation that beforeEach can be used to reset the test.each data table incorrect (i.e. the table is invariant at runtime)?
  2. How can I achieve the result I am looking for?
Share Improve this question edited yesterday jonrsharpe 122k30 gold badges268 silver badges475 bronze badges asked yesterday Simon OliverSimon Oliver 194 bronze badges 2
  • Yes, your expectation is incorrect. Just think about the control flow - the callback passed to beforeEach is only going to be called at test run time, whereas test.each is called at test discovery time. If you already know all of the data anyway, why not just write regular JS loops (ref)? – jonrsharpe Commented yesterday
  • Thanks Jon. I don't know the data ahead of time as the full task imports csv files (or will do if I can get it working) and each row may use two different data files. I am tempted to use loops, but thought the various each methods could handle this. – Simon Oliver Commented yesterday
Add a comment  | 

1 Answer 1

Reset to default 0
const dataArray = [['Data 3', 'd3'], ['Data 4', 'd4']];
dataArray.forEach(row => {
  describe('Test group using %s with tag %s', () => 
  {
    let groupData = [{'id':'01'},{'id':'02'}];
    let groupTag = '';
    let datafile = '';
    switch(row[1])
    {
    case 'd3': groupData = [{'id':'31'},{'id':'32'}]; break;
    case 'd4': groupData = [{'id':'41'},{'id':'42'}]; break;
    }
    datafile = row[0];
    groupTag = row[1];
    console.log('Beginning tests for '+groupTag+' using '+datafile+'\r\n groupData set to '+JSON.stringify(groupData[0])+' and '+JSON.stringify(groupData[1]));
    groupData.forEach(num => test('Test case ${num} [tag:sandbox]', () => 
      {
        console.log(groupTag+' - Running test '+num.id); 
        expect(num.id).toBeDefined(); //example test
      }));
  });
});
 

This got the 'desired' result, defining all the tests first, then running them

    console.log
      Beginning tests for d3 using Data 3
       groupData set to {"id":"31"} and {"id":"32"}
      Beginning tests for d4 using Data 4
       groupData set to {"id":"41"} and {"id":"42"}
      d3 - Running test 31
      d3 - Running test 32
      d4 - Running test 41
      d4 - Running test 42

hat tip to the linked question Using jest's test.each vs. looping with forEach
and https://stackoverflow/users/3001761/jonrsharpe for his comment.

本文标签: jestjsTrying to use beforeEach to modify the table sent to testeach within describeeachStack Overflow