通过动态测试用例进行 Jest 循环

如何在 Jest 中循环遍历动态测试用例?

我有以下这样的测试用例,我如何使用 it/test方法动态地创建测试用例。

下面是我尝试过的 ,但是它只是通过而不执行循环中的测试用例。

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

});
89638 次浏览

If one passes, they all will. So you only need one for a positive test. Ideally, you want 1 positive where the 2 numbers equal the sum, and a failure where you pass a string or something and throw an error.

TL/DR; You don't need 4 tests that all do the same thing. Also, you need to pull the looped test cases out of the parent test for the loop to work.

This will work just fine:

import jest from 'jest';
import { sumModule } from './';


const tests = [
{x: 1, y: 2, r: 3},
{x: 3, y: 4, r: 7}
];


describe('Adding method', () => {
for(let i = 0; i < tests.length; i++){
it('should add its params', () => {
const actual = sumModule(tests[i].x, tests[i].y);
expect(actual).toBe(tests[i].r);
});
}
});

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

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

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