テストの議論は、なぜかいつも「カバレッジ何%を目指すか」に吸い込まれていきます。しかしカバレッジは手段の計測値であって、目的ではありません。テスト戦略とは「何を・どの層で・どこまで検証し、何を検証しないか」というチームの合意です。
この合意がないチームでは、同じ振る舞いを3つの層で重複テストし、CIは30分かかり、リリースのたびに「よく落ちるテスト」を再実行して緑にする——という状態が生まれます。この記事では、その合意を組み立てるための判断基準をまとめます。
テストは何のためにあるか — 2つの価値
戦略の前に、テストの価値を分解しておきます。
- 回帰の検出: 変更が既存の振る舞いを壊したことを、本番より先に教えてくれる
- 設計へのフィードバック: テストしにくいコードは、たいてい結合が強すぎるコード。テストの書きにくさは設計の警報器
この2つを最大化し、維持コスト(実行時間・不安定さ・変更時の修正量)を最小化するのがテスト戦略の目的関数です。「テストを増やすこと」自体は目的ではありません。
テストピラミッド — 本質は「コストの階層」
ユニットテストを土台に、統合テストを中間に、E2Eテストを頂点に少しだけ——というテストピラミッドは、単なる比率の話ではありません[1]。本質は、上の層ほど1本あたりのコストが桁で高いという経済です。
| 層 | 検証対象 | 速度 | 失敗時の原因特定 | 安定性 |
|---|---|---|---|---|
| ユニット | 関数・クラス単体のロジック | ミリ秒 | 容易(範囲が狭い) | 高い |
| 統合 | 部品間の接続(DB・API・キュー) | 秒 | 中程度 | 中程度 |
| E2E | ユーザー視点の主要フロー | 分 | 困難(どこでも壊れ得る) | 低い |
E2Eテストは「本物に近い」ため魅力的ですが、遅く、不安定で、失敗しても原因が分かりません。GoogleのTesting Blogが10年前に「Just Say No to More End-to-End Tests」と書いた警告[2]は、いまも現役です。E2Eで検証するのは「主要な業務フローが繋がっていること」だけに絞り、ロジックの分岐は下の層で網羅する——これがピラミッドの実践的な意味です。
どの層でテストするかの判断基準
迷ったときの判断フローはシンプルです。
- 条件分岐・計算・変換のロジック → ユニットテスト。分岐の数だけケースを書く
- SQL・ORM・外部APIとの境界 → 統合テスト。モックではなく本物(コンテナで立てたDB等)に当てる。「モックしたDBに対するテスト」は、SQLの間違いを検出できません
- 設定・配線・デプロイの正しさ → 少数のE2E(スモークテスト)
- モジュール間の依存ルール → アーキテクチャテスト。モジュラモノリスの記事で書いた「境界をCIで強制する」はテスト戦略の一部です
ここで効いてくるのが設計との相互作用です。ロジックをI/Oから分離する(純粋な関数に切り出す)ほど、速いユニットテストでカバーできる範囲が広がり、ピラミッドは自然に太い土台を持ちます。テストの書きにくさを感じたら、テストを頑張る前に分離を疑ってください。
「何をテストしないか」を明文化する
すべてをテストする予算はありません。だからこそ、テストしないものを意図的に決めます。
- フレームワークの動作(ORMが正しくSQLを発行するか等)はテストしない。それはフレームワークのテストの仕事
- 自明な委譲・getter/setterはテストしない。壊れようがないコードのテストは維持コストだけが残る
- UIのピクセル・文言の細部は、変更頻度が高いなら自動テストから外す(スナップショットテストの割れ窓化を防ぐ)
- 逆に、金額計算・権限・データ削除のような「間違えたら事故」の領域は、分岐を完全網羅する
この「やらないリスト」がないチームのカバレッジ目標は、テストしやすい場所だけが厚くテストされるという形骸化を招きます。カバレッジは「どこが検証されていないか」を見る診断ツールとして使い、目標値として崇めないことです。
壊れやすいテスト(Flaky Test)は品質問題として扱う
「たまに落ちるけど再実行すれば通るテスト」を放置すると、チームは赤いCIに慣れます。赤に慣れたCIは、本物の回帰を素通しします。
- flakyなテストは検疫(quarantine)して即座に本流から外し、チケット化して直す(直せないなら消す)
- 原因の大半は、時刻依存・実行順序依存・共有状態・非同期の待ち方の4つ。テストごとの独立性(毎回まっさらなデータで始める)を規約にする
- 「再実行ボタンを押す文化」が根づく前に手を打つ。これは技術的負債の中でも複利が大きい種類です
CIの信頼性は、ループエンジニアリングで書いた「検証信号の質」そのものです。AIエージェントに開発を任せる場合、flakyなテストはループを直接壊します——人間なら「またこれか」と無視できても、エージェントは偽の失敗を本気で直しに行くからです。テストの決定性は、AI時代にはチームの生産性の前提条件になります。
戦略をチームの合意にする
最後に、戦略を個人の美学からチームの運用に変える手順です。
- リスクマップを作る: 「壊れたら一番痛い機能はどこか」を業務側と合意する(テスト投資の優先順位はここから)
- 層ごとの方針を1枚に書く: 何をユニットで・何を統合で・E2Eは何本まで、を明文化してリポジトリに置く
- CIの時間予算を決める: 「プルリクエストのチェックは10分以内」のような予算を決め、超えたら並列化・分割・テストの見直しをする
- 新機能の「テスト完了の定義」をレビュー観点に入れる: テストの有無ではなく、リスクに見合った層で書かれているかを見る
まとめ
- テスト戦略とは「何を・どの層で・どこまで検証し、何を検証しないか」のチーム合意
- ピラミッドの本質はコストの経済。ロジックは下層で網羅し、E2Eは主要フローの疎通確認に絞る
- 境界のテストは本物に当てる。モックだらけの統合テストはSQLの間違いを見つけられない
- カバレッジは診断ツールであって目標ではない。「やらないリスト」を明文化する
- flakyテストは検疫して直す。赤に慣れたCIは回帰を素通しし、AIエージェントのループも壊す
良いテストスイートの条件は「多いこと」ではなく、「緑なら安心してデプロイでき、赤なら本当に何かが壊れている」という信頼です。その信頼こそが、リリース速度と品質を同時に上げる唯一の資産です。
参考文献・一次情報
- [1]
- [2]