使用 test.each 简化重复的 Jest 测试用例
问题
我有时会遇到这样的情况:大部分测试用例都遵循类似的步骤。这种情况最常发生在对辅助函数/实用函数进行单元测试时。给定某些参数,检查实际结果是否等于预期结果。如此反复。随着测试用例数量的增加,测试套件就会变得臃肿不堪。
以下示例为虚构作品:
const add = (a, b) => a + b;
describe("'add' utility", () => {
it("given 2 and 2 as arguments, returns 4", () => {
const result = add(2, 2);
expect(result).toEqual(4);
});
it("given -2 and -2 as arguments, returns -4", () => {
const result = add(-2, -2);
expect(result).toEqual(-4);
});
it("given 2 and -2 as arguments, returns 0", () => {
const result = add(2, -2);
expect(result).toEqual(0);
});
});
解决方案
我考虑过使用抽象方法来避免这种样板代码,经过几次谷歌搜索后,我找到了Jest 的test.each工具。
这个辅助函数鼓励你创建一个数组cases,在其中存储参数和预期结果,然后遍历整个数组来运行被测函数并断言结果。
例如test.each:
const add = (a, b) => a + b;
const cases = [[2, 2, 4], [-2, -2, -4], [2, -2, 0]];
describe("'add' utility", () => {
test.each(cases)(
"given %p and %p as arguments, returns %p",
(firstArg, secondArg, expectedResult) => {
const result = add(firstArg, secondArg);
expect(result).toEqual(expectedResult);
}
);
});
笔记
好处:
- 更容易添加新的测试用例
- 减少样板代码
可能的缺点:
- 抽象化程度越高,有些人可能觉得越没必要。
我认为对cases数组中的元素添加注释可以提高可读性并减少脑力消耗。
// first argument, second argument, expected result
const cases = [[2, 2, 4], [-2, -2, -4], [2, -2, 0]];