フロントエンドテストを学ぶ前の案内【React】
はじめに
先日、React/ Next.js の勉強会で、テストについて取り上げました 🫐
自動テストというトピックは、意外ととっつきづらく、
- 「チーム内でテストコードを書く習慣がない」
- 「個人開発・学習でテストを書く重要性がイマイチわかっていない」
というケースも、少なくないかと思います。
なので今回は、テスト初心者の方向けに、
フロントエンドテストを書き始める前の「基礎知識」を中心にまとめました!
テスト導入の第一歩として、参考になれば嬉しいです 🙌
テストとは?
ソフトウェア テストは、アプリケーションが意図したとおりに動作し、バグや欠陥がないことを検証するプロセスです。
(中略)
ソフトウェア テストを実行するには、テスターが手動でソフトウェアを操作するか、テストスクリプトを実行するか、自動テストツールを使用します。
上記の引用の通りですが、テストは、
「プログラムが期待通りに動作するかを、確認する作業」といえます。
そして、この作業は超ざっくり分けると、2 つのアプローチがあります:
- 手動テスト
- 自動テスト
例えば、下記のようなログインフォームで考えてみます:
期待する動作:
- メールアドレスとパスワードを入力して、「ログイン」ボタンを押すと、ログインできる
- 不正なメールアドレス形式の場合は、エラーメッセージが表示される
- パスワードが短すぎる場合は、エラーメッセージが表示される
通常、この実装をした後、開発者は npm run dev
などでサーバーを起動し、
ブラウザ上で実際に操作して、動作確認をしますよね。
これは「手動テスト」と言えます。
そして、この確認作業は「自動化」することができます。
上記の「期待する動作」を、プログラムとして記述することで、
コマンド一つで、自動的に確認できるようにするのです。
これが「自動テスト」であり、一般的に「テストコード」と呼ばれるものです!
自動テストは何が嬉しいのか?
テスト出力コンソールの例
そもそも、実際の開発現場では、
- 機能追加やリファクタリング後、既存の機能が正常に動作するか確認が必要
- コードレビュー時に、他メンバーの実装が仕様通りか確認が必要
その際、簡単に想像できますが、
アプリケーションの規模が大きくなると、確認作業が大変になってきます
- 確認項目が多すぎて、人為的なミスや確認漏れが発生したり、
- 他メンバーが加えた変更の場合、修正の影響範囲まで把握しきれない
- コード量の増加に比例して、バグ発生のリスクが上昇。。
動作確認を仕組み化することで、
将来にわたってずっと動作が正常であることを担保できるので、安心ですね 👍
では、どのようにテストするのか?
フロントエンドテストで、主要なテストの種類として、
下記を挙げます:
- 単体テスト(Unit Tests)
- 統合テスト(Integration Tests)
- E2E テスト(End-to-End Tests)
単体テスト(Unit Tests)
- 最小単位(関数やコンポーネント)のテスト
- 例:バリデーション関数、UI コンポーネントの表示確認
統合テスト(Integration Tests)
- 複数のロジック・コンポーネントなどを組み合わせたテスト
- 例:ログインフォーム全体の動作確認
- (結合テストと呼ばれることもある)
E2E テスト(End-to-End Tests)
- ユーザーの実際の操作シナリオをブラウザ環境でテスト
- 例:ログイン → 商品購入 → 決済までの一連の流れ
それぞれのテストの特徴
ここで重要なのは、
各テストの種類は、トレードオフの関係にあるということです:
当たり前ですが、
ユーザーは、1 つの関数やコンポーネントを区別して、アプリを使用しません。
画面上に表示された、複数の機能を総合して使用します。
なので、単体テストは比較的簡単に書け、実行速度は早いですが、
実際のユーザーフローとは、少し乖離がありますね!
テスト戦略: より良いプラクティスはある?
前項で確認した通り、
各テストの種類の、どれか 1 つが「最適」ことはありません。
アプリケーションの特性に応じて、バランスの取れた「テスト戦略」を検討することが大切です!
なのでここでは、代表的なテスト戦略を 1 つ紹介します。
Kent C. Dodds が提唱する「Testing Trophy」です:
出典:https://kentcdodds.com/blog/the-testing-trophy-and-testing-classifications
これは、一言で言うと、
「上記の面積の比率でテストを書くべき」という考えです。
と言うのも、従来の「テストピラミッド」というピラミッド型の戦略図では、
単体テストを多く書く戦略が、支持されていました。
しかし、この「テスティングトロフィー」では、
統合テストを中心に据えることを推奨しています。
その理由は:
- 実際のユーザーの使用パターンに近いテストができる
- E2E テストに比べ、コストパフォーマンスが良い
- ユニットテストとは違い、複数のコンポーネントの相互作用を確認できる
そして、現状はあたり前になりつつある、
静的解析(ESLint, TypeScript)を基盤にしている点も、ポイントですね!
実際にフロントエンドテストツールを選定
各テストの種類に対応する、主要なツールは、:
E2E テスト:
- Cypress
- Playwright
筆者の一押しは、Playwright です!
単体テスト・統合テスト・コンポーネントテスト:
- Jest
- Vitest
- React Testing Library
最近は、React Testing Library + Vitest が良きです!
📝 Note: ユニットテストと統合テストの境界は曖昧で、厳密な区別は不要です。
静的解析:
- ESLint
- TypeScript
これはもう、当たり前に入れときたいですね!
(husky なども一緒に!)
おわりに
最後まで読んでいただだき、ありがとうございます 🥳
下記の、React ハンズオン勉強会での、振り返りのような記事ですが、
テスト導入の第一歩として、当記事が参考になれば幸いです!
そして、もし、間違いや補足情報などがありましたら、
ぜひコメントを追加してください!
Happy Hacking :)
参考
Discussion