🧪

Jest each修飾子を使用したParameterized Test

2024/02/24に公開

はじめに

Jestを使用してテストを書いていると、パターン化されたテストを書く場合があります。
そのような場合には、each修飾子を使用することで、パラメータ化されたテストを書くことができます。

each修飾子について

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

each修飾子は、配列を引数として受け取り、その配列の要素を使ってテストを実行できます。
書き方は3通りあります。それぞれの書き方について説明します。

ここでは、以下のような関数をテストすることを考えます。みなさんご存知のFizzBuzzです。
3で割り切れる場合はFizz、5で割り切れる場合はBuzz、3と5で割り切れる場合はFizzBuzz、それ以外の場合はその数値を文字列に変換して返します。

type ResultFizzbuzz = (num: number) => string

const resultFizzbuzz: ResultFizzbuzz = (num: number) => {
  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}`;
}

Array of objects

オブジェクトの配列を引数として受け取ります。この場合、オブジェクトのプロパティを使ってテストを実行できます。
他の書き方と比べて冗長な書き方ですが、型推論がきくため、型安全なテストを書くことができます。

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

Array of arrays

配列の配列を引数として受け取ります。この場合、配列の要素を使ってテストを実行できます。

オブジェクト配列と比べてスムーズに書くことができます。

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]> = [
 ...
]
// OK: as constを使用しても回避できる
const table = [
  ...
] as const

Template literals

テンプレートリテラルを引数として受け取ります。この場合、テンプレートリテラルのプレースホルダを使ってテストを実行できます。

テーブルの見た目がわかりやすくなり、視認性が向上します。

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

さいごに

each修飾子を使用することで、パラメータ化されたテストを書くことができます。
パターン化されたテストに使用することで、テストの冗長性を減らし、視認性を向上させることができます。

参考

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

Discussion