🧪

Jest eachでパラメータ化テストを実装する

に公開

Jestのeach修飾子を使って、パラメータ化テスト(Parameterized Test:複数のテストケースを効率的に記述する手法)を実装する方法を紹介します。

each修飾子とは

複数のテストケースをループ処理で実行できる機能です。同じロジックで異なる入力値をテストする場合に便利です。

公式ドキュメント: https://jestjs.io/ja/docs/api#each

サンプル: FizzBuzz関数

以下のFizzBuzz関数をテストします。

type ResultFizzbuzz = (num: number) => string

const resultFizzbuzz: ResultFizzbuzz = (num) => {
  const isFizz = num % 3 === 0
  const isBuzz = num % 5 === 0
  const isFizzBuzz = isFizz && isBuzz

  if (isFizzBuzz) return 'FizzBuzz'
  if (isFizz) return 'Fizz'
  if (isBuzz) return 'Buzz'
  return `${num}`
}

書き方1: オブジェクトの配列

オブジェクトのプロパティを使ってテストを実行します。

it.each([
  { num: 1, expected: '1' },
  { num: 2, expected: '2' },
  { num: 3, expected: 'Fizz' },
  { num: 5, expected: 'Buzz' },
  { num: 15, expected: 'FizzBuzz' },
])('FizzBuzz Test', ({ num, expected }) => {
  expect(resultFizzbuzz(num)).toBe(expected)
})

メリット:

  • プロパティ名で意味が明確
  • TypeScriptの型推論が効く

デメリット:

  • やや冗長

書き方2: 配列の配列

配列の要素を順番に引数として受け取ります。

it.each([
  [1, '1'],
  [2, '2'],
  [3, 'Fizz'],
  [5, 'Buzz'],
  [15, 'FizzBuzz'],
])('FizzBuzz Test', (num, expected) => {
  expect(resultFizzbuzz(num)).toBe(expected)
})

メリット:

  • 簡潔で見やすい
  • 記述量が少ない

デメリット:

  • 引数の順序を間違えやすい

配列を変数に切り出す場合の注意

型を明示的に指定する必要があります。

// ❌ NG: 型推論が効かずエラー
const table = [
  [1, '1'],
  [2, '2'],
  [3, 'Fizz'],
  [5, 'Buzz'],
  [15, 'FizzBuzz'],
]

// ✅ OK: 型を明示的に指定
const table: Array<[number, string]> = [
  [1, '1'],
  [2, '2'],
  [3, 'Fizz'],
  [5, 'Buzz'],
  [15, 'FizzBuzz'],
]

it.each(table)('FizzBuzz Test', (num, expected) => {
  expect(resultFizzbuzz(num)).toBe(expected)
})

// または as constで型アサーション
const table2 = [
  [1, '1'],
  [2, '2'],
  [3, 'Fizz'],
  [5, 'Buzz'],
  [15, 'FizzBuzz'],
] as const

書き方3: テンプレートリテラル

テンプレートリテラルを使ってテーブル形式で記述します。

it.each`
  num  | expected
  ${1} | ${'1'}
  ${2} | ${'2'}
  ${3} | ${'Fizz'}
  ${5} | ${'Buzz'}
  ${15} | ${'FizzBuzz'}
`('FizzBuzz Test', ({ num, expected }) => {
  expect(resultFizzbuzz(num)).toBe(expected)
})

メリット:

  • テーブル形式で視認性が高い
  • データ構造が直感的

デメリット:

  • TypeScriptの型推論が効かない

まとめ

each修飾子を使うことで、パラメータ化テストを効率的に記述できます。

選択のガイドライン:

  • 型安全性重視: オブジェクトの配列
  • シンプルさ重視: 配列の配列
  • 視認性重視: テンプレートリテラル

パターン化されたテストケースを効率的に記述し、テストの保守性を向上させましょう。

参考

https://jestjs.io/ja/docs/api#each

Discussion