Jest looping through dynamic test cases

Viewed 81934

How do I loop through dynamic test cases in Jest?

I have test cases like the following how do I dynamically create jest test case using it/test methods.

Here is what I have tried , However it just passes without excuting the test cases in the loop.

    const mymodule = require('mymodule');

    const testCases = [
        {q: [2, 3],r: 5},
        {q: [1, 2],r: 3},
        {q: [7, 0],r: 7},
        {q: [4, 4],r: 8}
    ];

    describe("Test my Math module", () => {
        test("test add method", () => {
            for (let i = 0; i < testCases.length; i++) {
                const { q,r } = testCases[i];
                it(`should  add ${q[0]},${q[1]} to ${expected}`, () => {
                    const actual = mymodule.add(q[0] + q[1]);
                    expect(actual).toBe(expected);
                });
            }
        });
    
    });
6 Answers

There's an in-built way to do this: test.each(table)(name, fn, timeout)

e.g.

test.each([[1, 1, 2], [1, 2, 3], [2, 1, 3]])(
  '.add(%i, %i)',
  (a, b, expected) => {
    expect(a + b).toBe(expected);
  },
);

where each inner array in the 2D array is passed as args to the test function.

If anyone wondering how this can work for a single input function here is an example

const testData = [
      ['input1', 'output1'],
      ['input2', 'output2'],
      ['input3', 'output3'],
]

test.each(testData)('myFunc work correctly for %s',(input, output) =>{
        expect(yourFunc(input)).toBe(output)
})

https://jestjs.io/docs/en/api#testeachtablename-fn-timeout

You can use classic JS, it is more readable and with less code:

[
  { input: [2, 3], output: 5 },
  { input: [1, 2], output: 3 },
].forEach(({ input, output }) => {
  it(`works correctly for ${input}`, () => {
    // ...

    expect(...).toBe(output);
  });
})

An alternative solution:

const cases = [
  { q: [2, 3], r: 3 },
  { q: [1, 2], r: 3 },
  { q: [7, 0], r: 7 },
  { q: [4, 5], r: 8 }
];

describe("Test cases for math module", () => {
  cases.forEach((el, i) => {
    let value1 = el.q[0]
    let value2 = el.q[1]
    let value3 = el.r

    test(`the sum of ${value1} and ${value2} equals ${value3}`, () => {
      expect(value1 + value2).toBe(value3)
    })
  })
})

Test results

When all tests pass:

enter image description here

In case one or more tests fail, it will show like so:

enter image description here

I did all the tests in CodeSandbox, if you want to play with the code click here

For loop works in jest, No need to use inbuilt function without any reason!

 test('adding positive numbers is not zero', () => {
  for (let a = 1; a < 10; a++) {
    for (let b = 1; b < 10; b++) {
      expect(a + b).not.toBe(0);
    }
  }
});
Related