🔨

関数全部をテストするな!!!

2022/07/16に公開

In short: もっと優先度の高い箇所からユニットテストしていこう。関数単位のユニットテストは単なる自己満になりやすい。

関数単位のユニットテストは優先度が低い

関数のテストは書きやすいし、テストカバレッジも上がって気持ちがいいものです。でも、 zerofill や milliSecToSec のような関数の動作が保証されても、大して嬉しくありませんよね? 本当にチェックする必要がありますか? 僕は不要だと思います。

it('test zerofill', () => {
  expect(zerofill(3, 2)).toBe('03');
  expect(zerofill(42, 2)).toBe('42');
});

↑これが保証されて、本当に嬉しいですか?

関数単位よりも、まずはアプリケーションの仕様のテストをしましょう。 それが最優先です。アプリが正常に動くかテストすれば、各関数も自然にテストされるはずです。

また、アプリの仕様が変わったりアルゴリズムごと変えた場合、関数ごと使わなくなる可能性もあります。

とにかく、まずはアプリ仕様をテストしましょう。 十分に仕様のテストができるまでは関数単位のテストは不要です。

関数単位のテストを書くべき場合

細かい関数をテストしても大して恩恵がなく、コスト>メリットとなりやすいです。ただ、 コーナーケースや境界値のテストはやったほうが良いです。 関数のコーナーケースまでアプリのテストを通じて検証しようとすると逆に面倒です。そこは素直に関数のテストを書きましょう。

とは言いつつ、コーナーケースや境界値のテストが必要な関数はあまり多くありません。そのため やはり関数単位のテストはほとんど要らないはずです。

付録: 仕様のテストの具体例

it('can close modal with escape key', () => {
  const onClose = jest.fn();
  render(<Modal onClose={onClose}/>);
  fireEvent.keyDown(document.body, { code: 'Escape' });
  expect(onClose).toBeCalled();
});

↑こういう感じのテストです。もしこのテストがパスすれば、「document.body で Escape キーの keydown イベントが発火したら、モーダルが閉じる」ことが保証されます。

Discussion