Open7

Jest + React Testing Libraryのテスト方針を考える

nori0__nori0__

自身のプロジェクトで Jest を使っているがごちゃごちゃになってきているためきちんとテスト方針を決めたい。情報収集する

nori0__nori0__

どういった実装をテストすべきなのか

https://zenn.dev/longbridge/articles/38572a8a9970f4

  • 個々の小さなコンポーネントをテストするより個々のコンポーネントが連携して動作するようなコンポーネントをテストすべき
    • 個々のコンポーネントが連携して動作するようなコンポーネントとは、Atomic Design でいう pages や templates ?
  • ユーザーが操作する部分のテストをすべき
  • 実装の詳細はテストすべきでない
    • リファクタリングで壊れてしまうため
nori0__nori0__

自分の経験的にお勧め

  • ロジック周りは網羅的にテストしたい
    • そのため複雑なロジックは custom hooks 切り出し、網羅的にテストするのが良かった
nori0__nori0__

https://qiita.com/mrnaoki/items/3fd211deb8711fae8204#テストの方針の結論

1.「実装の詳細」をテストしない
「実装の詳細」を操作するようなテストを書いてはいけません。なぜならそれは「壊れるべきでないときに壊れるテスト」と「壊れるべきときに壊れないテスト」の両方に繋がってしまうからです。

「壊れるべきでないときに壊れるテスト」

実装の詳細をテストしているということは、その実装の詳細部分を変更するとテストが壊れるということです。つまりリファクタで簡単に壊れまくります。

「壊れるべきときに壊れないテスト」

しかし、「実装の詳細」に集中した粒度の小さいテスト(ユニットテストなど)しか行っていないと、各単体のコンポーネントや機能粒度ごとの挙動しか保証できず、コンポーネントや機能同士が連携したときの挙動を担保することができません。
そのため、実装の詳細のテスト(ユニットテストなど)だけだと、実際のアプリの「全体が連携したときの挙動」は壊れているのに、テストが間違って通ってしまうことがあります。

実装の詳細をテストしないためのポイント

「ユーザーから見えるもの」という視点でテストする。「ユーザーから見えないもの」はテストしない。
テストで直接Component内のStateやメソッドをいじらない。
ユニットテストではなく、インテグレーションテストを最も書くようにする。
EnzymeのShallow Renderingは使わないようにする。
Snapshotテストをむやみに使わない

他の方針

  1. 外部システムに依存するテストはしない
  2. 「モック」はできるかぎり少なくする
  3. 「コードカバレッジ」より「ユースケースカバレッジ」を意識する
nori0__nori0__

ダメ絶対なこと

CI実行時間が長い

https://zenn.dev/nori0__/articles/event-report-encraft-18-front-test#上手く付き合うコンポーネントテスト

CIを早くする方法は色々ある

並列実行(ワーカーレベル)
並行実行(ジョブレベル)
ランナーを使い分ける

jest では並行実行(ジョブレベル)を導入するとテストファイル数で並行に実行するようになるため
テストファイルは機能ごとなど分割して行ったほうが良さそう