テスト戦略と哲学
テストピラミッド・テストトロフィーを基盤とした、プロダクトに合わせたテスト戦略の立て方
テスト戦略とは、どの層にどれだけのテストを配置するかの方針だ。テストには有限のリソース(実装コスト・実行時間・メンテナンス)が伴うため、投資対効果を考えた優先付けが必要になる。優れたテストは「仕様のドキュメントとして機能する」「デグレードを自動検出する」「設計への圧力として品質を向上させる」という三つの目的を持つ。
テストピラミッドはMike Cohnが提唱したモデルで、底辺に多数のユニットテスト・中間に統合テスト・頂点に少数のE2Eテストを置く。上位に行くほど遅く・壊れやすく・高コストになるため、下位に多くのテストを持つことが効率的とされた。一方、Kent C. DoddsはテストトロフィーモデルでIntegration Test(統合テスト)を中心に置くべきと主張する。ユニットテストは実装詳細のテストになりがちで、統合テストのほうが「動く保証」として価値が高いという主張だ。
TDD(Test-Driven Development)はテストを先に書き、テストを通すコードを最小限実装した後にリファクタリングするサイクル(Red-Green-Refactor)を繰り返す。TDDの真の価値はテストカバレッジではなく「設計への圧力」であり、テストしにくいコードが書かれた瞬間に設計の問題が明らかになる。テストを後から書く場合でも、テストしやすい設計を意識することが重要だ。
コードレビューで着目するポイント
- テストが実装詳細(内部のメソッド名・プライベートな変数)に依存していないか
- テストのアサーションが「ユーザーが期待する動作」を検証しているか
- 一つのテストケースが複数の独立した振る舞いを検証していないか(1テスト1アサーション原則)
- テストコードの命名が「何をテストしているか」を日本語または英語で明示しているか
- テストの前提条件(Arrange)・操作(Act)・検証(Assert)が読み取りやすい構造になっているか
- テストが実行順序に依存していないか(共有状態の残留がないか)
- テストカバレッジが高い一方で重要なエッジケースが抜けていないか
典型的なアンチパターン
テストのないリリース: テストが書かれておらず、手動確認のみで本番にリリースする。変更のたびに全機能を手動確認するコストが増大し、リリース頻度が下がる。
壊れやすいテスト(Brittle Tests): CSSクラス名やDOMの深い階層に依存したテストが、UIのスタイル変更だけで失敗する。実装詳細への依存がテストのメンテナンスコストを押し上げる。
テストのための複雑な設定: テストごとに100行以上のセットアップが必要な状態。設計の問題(密結合・依存が多すぎる)をテストコードが示している。テストへの圧力として設計を見直すべきサイン。
参考リソース
- Vladimir Khorikov『Unit Testing: Principles, Practices, and Patterns』(Manning、2020)
- Kent C. Dodds「Testing Trophy」 https://kentcdodds.com/blog/the-testing-trophy-and-testing-classifications
- Kent Beck『Test-Driven Development: By Example』(Addison-Wesley、2002)
- Martin Fowler「TestPyramid」 https://martinfowler.com/bliki/TestPyramid.html
- Testing Library https://testing-library.com — 実装詳細ではなくユーザーの視点でテストするライブラリ
- 1. 📄アーキテクチャスタイル
- 2. 📄ドメインモデリング
- 3. 📄モジュール分割と依存管理
- 4. 📄データモデリング
- 5. 📄API設計
- 6. 📄整合性とトランザクション
- 7. 📄非同期処理(Queue/Event)
- 8. 📄キャッシング
- 9. 📄ユーザーリサーチ
- 10. 📄情報アーキテクチャ
- 11. 📄インタラクションデザイン
- 12. 📄UX原則とヒューリスティクス
- 13. 📄アクセシビリティ(UX観点)
- 14. 📄UXメトリクス
- 15. 📄スケーラビリティ
- 16. 📄可用性とレジリエンス
- 17. 📄オブザーバビリティ
- 18. 📄環境・インフラ設計
- 19. 📄データマイグレーション
- 20. 📄セキュリティ設計原則
- 21. 📄データ保護とマルチテナント
- 22. 📄LLMセキュリティ
- 23. 📄ビジュアルデザイン原則
- 24. 📄デザインシステム
- 25. 📄コンポーネント設計
- 26. 📄スタイリング
- 27. 📄設計原則
- 28. 📄デザインパターン(GoF)
- 29. 📄エンタープライズパターン
- 30. 📄クリーンコード
- 31. 📄リファクタリング
- 32. 📄型設計とコントラクト
- 33. 📄関数型プログラミング概念
- 34. 📄エラーハンドリング
- 35. 📄テスト戦略と哲学
- 36. 📄テスト種別(機能テスト)
- 37. 📄テスト種別(UI・ビジュアル)
- 38. 📄テスト種別(契約・境界)
- 39. 📄並行処理・マルチスレッド
- 40. 📄パフォーマンス最適化
- 41. 📄ドキュメント管理
- 42. 📄バージョン管理と開発プロセス
- 43. 📄脅威モデリング
- 44. 📄通信保護(TLS)
- 45. 📄暗号化・機密情報管理
- 46. 📄認証・セッション管理
- 47. 📄認可・アクセス制御
- 48. 📄入力バリデーション
- 49. 📄インジェクション攻撃
- 50. 📄正規化(データベース正規化)