はじめに
皆さんはフロントエンドのテストについて、どのように取り組んでいますか?
近年はツールやフレームワークの進化によってテスト環境が整ってきました。
それでも「テストを書くこと」自体が目的化してしまい、本来の価値を見失うケースも少なくありません。
本記事では、私自身が実務を通じて気づいた、フロントエンドにおけるテスト戦略・考え方について整理してみます。誰かの参考になれば幸いです。
何をテストするべきか
テスティングトロフィーに従い、主に振る舞いに着目したテスト、ユーザーから見える最終的な結果を検証することを意識しています。
例えば、Reactの状態(state)の更新関数が想定される引数で実行されることではなく、その更新関数が実行されたことによる結果を検証します。
// 実装の詳細
expect(mockSetState).toHaveBeenCalledWith(...)
// ユーザーから見える結果
expect(screen.getByText('成功しました')).toBeInTheDocument()
また、モックを多用してしまうと、現実からかけ離れた「都合の良い世界」を作ってしまいがちです。外部依存(API、時刻など)は必要に応じてモックしつつ、ユーザーインタラクションを起点とした一連のフローを、できるだけ実際に近い形でテストすることを心がけています。
私は以下の点を意識することとしました。
-
アプリケーションの振る舞いの正しさを優先する
- ロジックをカスタムフックに抽出したとしても、優先するのはロジックのテストではなく、使用側から見たアプリケーションの最終的な振る舞いを検証すること
- ただし、ビジネスクリティカル、もしくは非常に複雑なロジックに関してはユニットテストで補強
-
features/配下のindex.tsxなど、Container相当のコンポーネントに対してテストファイルを作り、インテグレーションテストを実装
-
事故や不具合が許されない領域に関しては多層でテストする
- システムの要となる重要領域は、ユニット・インテグレーション・E2Eテストを組み合わせて確認すること
ユーザにとってはUIがすべて(アプリケーションの視認できる部分が体験そのもの)であり、内部でどんな処理が行われているかは関心ありません。フロントエンド実装者は、その「見える部分」を通じてユーザとシステムをつなぐ役割を担っています。
だからこそ、ユーザの操作に対してアプリケーションがどう振る舞うかをテストすることは本質的なアプローチだと言えるでしょう。
カバレッジ率
「うちのチームは、テストカバレッジ率80%を下回ってはいけません。」
「(PRレビューにて)おいおい、ここのテストカバレッジ足りてないぞ!」
こうしたルールの背景には、組織的・政治的な事情があることも多く、個人で抗うのは容易でありません。結果として、カバレッジを稼ぐためだけのテストが量産されます。
カバレッジを稼ぐためだけのテストは、偽りの安心感をもたらし、最終的にはメンテナンスコストばかりが膨らんでしまいます。「価値 < メンテナンスコスト」となってはいないか見直してみることも大切です。
実装の硬直化
プロジェクトの初期段階など、仕様や設計が変わりやすい時期に注意が必要です。この段階で実装の詳細に踏み込んだテストを過剰に書いてしまうと、少しの変更が大量のテスト失敗を引き起こします。
こうなると、開発者は次第に変更に対して心理的な抵抗感を抱くようになります。
本来行うべきであった設計の改善やリファクタリングが避けられるようになるので、適切な粒度でテストを配置することが大切ですね。
過剰なテスト
私自身、テストコードの実装が慣れてきた場合、コードベースの様々な箇所に対してテストを実装してしまったことがあります。楽しさのあまり、書ける部分はとにかく書こうとすると、価値の低いテストで溢れてしまいます。
一度立ち止まり、本当にこのテストは必要かどうかを考えることを意識しております。
テストだけでは品質は保証されない
忘れてはいけないのが、不具合の多くは「必要なコードがそもそも存在しない」「認識の誤り」から生まれるということです。つまり、誤った実装にテストコードを当てても、間違った結果を正しいと確認してしまいます。
テストの前にできること
テスト以前に、実装の質を高めることが重要だと思います。
- TypeScriptの型を正しく活用する
- プロジェクト固有のルールをLintで強制する(カスタムルールなど)
- シンプルで読みやすい実装を心がける
特にTypeScriptの型システムを正しく活用できれば、それだけでユニットテスト等で検証する内容をカバーでき、結果として多くのバグを防ぐことが可能だと考えます。
まとめ
- 振る舞いをテストする: 実装の詳細ではなく、ユーザーから見える結果を検証
- モックは最小限に: できるだけ実際の動作に近い形でテスト
- カバレッジは手段: 数値より価値を重視し、「価値 < メンテナンスコスト」に注意
- 書きすぎない: 一度立ち止まって、本当に必要かを考える
- テストの限界を知る: テストだけでは品質保証されない
- 型や静的解析を活用: テストの前にできることをやる
もちろん、プロジェクトのフェーズ・背景により適切なテスト戦略は変わってきますが、本記事が誰かの参考になれば幸いです。
もしご意見や改善点がありましたら、ぜひコメントなどでご指摘ください。