前陣子在替typescript邏輯寫單元測試需要多種test case來驗證.正當寫多個test() function覺得麻煩時,突然想到jest是否有提供像C# NUnit TestCase attribute的功能,能將多個test case透過function parameter帶入同一個測試function呢?
[TestCase(12, 3, 4)]
[TestCase(12, 2, 6)]
[TestCase(12, 4, 3)]
public void DivideTest(int n, int d, int q)
{
Assert.AreEqual(q, n / d);
}
查了一下發現真的有類似的API, 可以透過test.each這個介面將test cases以陣列, 物件 或table的形式帶入
test.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('.add(%i, %i)', (a, b, expected) => {
expect(a + b).toBe(expected);
});
test.each([
{a: 1, b: 1, expected: 2},
{a: 1, b: 2, expected: 3},
{a: 2, b: 1, expected: 3},
])('.add($a, $b)', ({a, b, expected}) => {
expect(a + b).toBe(expected);
});
test.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`('returns $expected when $a is added $b', ({a, b, expected}) => {
expect(a + b).toBe(expected);
});
從範例中也看到可以使用 %
跟 $
的方式將參數帶進test description
個人是習慣用物件的方式, 可以透過property描述參數名稱, 比較語意化.以下是我撰寫的測試案例
import {groupArray} from "./array";
describe('groupArray', () => {
test.each(
[
{inputArr:[1,1,1,1], groupNum: 1, expected: [[1],[1],[1],[1]]},
{inputArr:[1,1,1,1], groupNum: 2, expected: [[1,1],[1,1]]},
{inputArr:[1,1,1,1], groupNum: 3, expected: [[1,1,1],[1]]},
{inputArr:[1,1,1,1], groupNum: 4, expected: [[1,1,1,1]]},
{inputArr:[1,1,1,1], groupNum: 5, expected: [[1,1,1,1]]},
{inputArr:['a','b','c','d'], groupNum: 2, expected: [['a','b'],['c','d']]},
]
)
('should return $expected when input array is $inputArr and groupNum is $groupNum', ({inputArr, groupNum, expected}) => {
expect(groupArray(inputArr as any[],groupNum)).toEqual(expected);
});
});
實際執行測試可以看到各個參數皆為獨立的test case, 可以看到是哪個test case assert fail
但如果參數本身是陣列或物件的話印出來就不這麼語意化, 可能要試試看override toString()
可不可以印出語意化的文字
希望可以幫助大家節省寫測試的時間.