テストピラミッドとは?単体・結合・E2Eの配分と実装者向けテスト戦略設計
テストピラミッドは、自動テストを「単体テストを土台に厚く、E2Eテストを頂点に薄く」積み上げるバランス指針です。狭く深く検証するnarrowなテストほど下層に、広く浅く検証するbroadなテストほど上層に置く、という縦軸で層をとらえるのが要点です。この記事では3層の実行速度・保守コストの違い、Googleが示した目安「70:20:10」の読み方、各層の範囲選定とCI/CDへの組み込み、逆ピラミッド(アイスクリームコーン)の兆候、テスティングトロフィーとの使い分けまで、実装者がテスト配分を設計する視点で整理します。テストサイズの分類は判断ハブ記事に、回帰テストや結合の詳細は関連記事に接続します。
目次
まとめ:テストピラミッドは「配分の設計図」として読む
テストピラミッドの結論を先に示します。ピラミッドは「単体7・結合2・E2E1」といった比率そのものを守る規範ではなく、フィードバックの速い層に検証を寄せ、遅く脆い層への依存を減らすための配分の設計図です。下層ほど実行が速く安定し、上層ほど遅く壊れやすい——この非対称性が形の根拠です。
実装者が下す判断は3つに絞れます。第一に、単体テストで守れる仕様はできるだけ下層で守り、依存を注入して差し替え可能にする。第二に、結合テストの範囲を「外部境界を1つだけまたぐ」粒度で切り、束ねすぎない。第三に、E2Eは主要導線だけに絞り、それ以外は下層へ降ろす。この3つを外すと、E2Eが膨らんだ逆ピラミッド(アイスクリームコーン型)に傾き、実行時間と不安定さで自動テスト全体が信頼を失います。比率は目安、優先順位は「速い層を厚く」です。
テストピラミッドの構造とnarrow/broadという縦軸の意味
まず形と、なぜその形になるのかを押さえます。ピラミッドは3つの層と、層を貫く1本の縦軸で理解すると設計に落とし込めます。
単体・結合・E2Eの3層構造と実行速度・保守コストの非対称性
テストピラミッドは下から単体テスト(ユニットテスト)、結合テスト(統合テスト)、E2Eテストという3層構成です。単体テストは関数やクラス単体の振る舞いを検証し、ミリ秒単位で完了します。結合テストは複数のモジュールやデータベース・APIをまたいだ挙動を確かめ、E2Eテストはブラウザ操作を含むシステム全体の導線を通します。
層を分ける根拠は速度と保守コストの非対称性です。単体テストはJUnitやJest、pytestなどで数百件を秒単位に回せますが、E2EはPlaywrightやCypress、Seleniumで1シナリオに数秒から数十秒かかります。上層ほど外部要因(画面変更・ネットワーク・データ状態)で壊れやすく、失敗時の原因特定にも時間を要します。だから「速くて壊れにくい下層を厚く、遅くて壊れやすい上層を薄く」積む——これがピラミッド型の直接の理由です。
narrow(狭く深い)とbroad(広く浅い)で捉える層の縦軸
層の分け方を「テストの種類」ではなく「検証範囲の広さ」で捉え直すと、粒度の判断がぶれません。narrowなテストは対象を1つに絞って条件分岐を深くたどり、broadなテストは複数コンポーネントを一度に通して広く浅く確かめます。下層ほどnarrow、上層ほどbroadという縦軸で、ピラミッドは連続的に並びます。
この見方の利点は、境界が曖昧なテストの置き場所を決められる点にあります。たとえば「1つのサービスクラスとその依存リポジトリだけを本物でつなぐ」テストは、単体寄りのnarrowな結合として下から2層目に置く。「ログインから決済まで通す」テストはbroad寄りのE2Eとして頂点に置く。種類名で悩む前に、狭いか広いかで縦位置を決めると配分が一貫します。
Google目安「70:20:10」の読み方と提唱者の位置づけ
比率の代表例として、Googleが自社の技術ブログで示した「ユニット70%・統合20%・E2E10%」という目安がよく引用されます。あくまで一例であり、環境によって妥当な配分は動くという前提です。フロントエンド偏重のプロダクトなら結合層が厚くなり、バッチ処理中心なら単体層がさらに支配的になります。
概念の系譜も押さえておくと引用の精度が上がります。テストピラミッドという言葉は、Mike Cohn氏が2009年刊行の書籍『Succeeding with Agile』で示した図に由来し、その後Martin Fowler氏が自身のbliki(2012年の記事「TestPyramid」)で広めた、という整理が一般的です。数字を金科玉条にせず、「速い層に寄せる」という思想を各プロダクトの制約へ翻訳するのが、提唱の本来の趣旨です。
各層の役割分担と、実装者が下すテスト配分・自動化戦略の設計判断
形を理解したら、次は自分のコードベースにどう割り付けるかです。各層で「何を守り、何を上層に渡さないか」を決めます。
単体テスト層を厚くするための依存分離とテスト容易性の設計判断
下層を厚くできるかは、テストの書き方より先に「設計がテスト可能か」で決まります。外部依存(DB・時刻・乱数・外部API)を直接呼ぶコードは単体テストにできず、結合やE2Eへ押し上げられてピラミッドを崩す要因です。依存を引数やインターフェースで注入し、テスト時に差し替えられる形にすると、多くの仕様を下層で守れます。
実務では「ロジックと副作用を分離する」を基準にします。計算・分岐・バリデーションといった純粋なロジックは単体テストで網羅し、DB書き込みや通信は薄いアダプタに寄せて上層で最小限だけ確かめる。この分離ができていないコードは、テストが書きにくいだけでなく変更にも弱い信号です。テストピラミッドの土台づくりは、実質的にプロダクトコードの依存設計そのものです。
結合テスト層の範囲選定——どこまでを1つの結合として束ねるか
結合テストは、範囲を広げるほど遅く壊れやすくなり、狭めるほど単体との差がなくなります。設計判断の軸は「またぐ外部境界を1つに絞る」ことです。サービス層とDBを1つだけ本物でつなぐ、あるいは自サービスと1つの外部APIをスタブ越しに検証する、という粒度に切ると、原因特定が速く保守コストが跳ねません。
複数の外部境界(DBも外部APIもメッセージキューも本物)を一度にまたぐテストは、broadすぎて失敗要因が分離できず、E2Eの性格に近づきます。Martin Fowler氏はこれをnarrow integration testとbroad integration testに区別しました。実装者としては、1テスト1境界を基本形にし、どうしても複数境界が必要な導線だけをE2Eへ昇格させる——この線引きが結合層を健全な厚みに保ちます。
E2E層を薄く保つ設計と、テストサイズ(Small/Medium/Large)との対応
E2Eは「これが落ちたらリリースを止める」主要導線だけに絞ります。ログイン・購入・申込みといった収益や登録に直結する数本に限定し、入力バリデーションや表示分岐は下層へ降ろすのが原則です。E2Eで細かな条件網羅をやろうとすると、実行時間が膨らみ、少しのUI変更で大量に赤くなる不安定なスイートに変わります。
層の分類を実行環境の制約で言い換えた枠組みが、Googleの提唱する「テストサイズ(Small/Medium/Large)」です。プロセス内で完結するSmall、単一マシン内のMedium、ネットワークやマシンをまたぐLargeという分け方は、ピラミッドの縦軸を実行コストの観点で再定義したものです。テストサイズと単体・結合の対応関係、およびその実務的な使い分けは、判断ハブとして単体テストと結合テストの区分をGoogle流テストサイズで捉え直す解説にまとめています。本記事ではピラミッドの縦位置決めに必要な範囲に留めます。
テストピラミッドを採用する場面・見送る場面と典型的な失敗パターン
ここからは判断を言い切ります。ピラミッドは万能の型ではなく、プロダクトの性質によって形を変えるべき指針です。採用条件と、崩れる兆候、代替モデルとの使い分けを整理します。
アイスクリームコーン型(逆ピラミッド)に陥る失敗パターンと兆候
最も避けたい失敗が、E2Eが最も多く単体が最も少ない逆ピラミッド、いわゆるアイスクリームコーン型です。手動テストや画面操作の自動化から着手し、下層を整えないまま機能を足し続けると、この形に傾きます。兆候ははっきりしています。CIの完走に数十分かかる、特定のテストが理由不明に赤くなる(フレーキー)、失敗しても原因の画面まで追わないと分からない——どれかが出たら逆ピラミッドを疑うべきです。
是正は「上から下へ降ろす」順で進めます。壊れやすいE2Eが検証している分岐のうち、ロジックで確かめられるものを単体テストへ書き直し、E2Eは導線確認だけに痩せさせる。この付け替えは回帰の効率にも直結するため、範囲選定と自動化の判断はリグレッションテストの範囲選定と自動化の考え方と併せて設計すると無駄がありません。
テストピラミッドとテスティングトロフィーの選定基準と使い分け
2026年7月時点で、フロントエンド領域を中心にテスティングトロフィー(Testing Trophy)という別モデルが対比されます。Kent C. Dodds氏が提唱したこのモデルは、結合テストを最も厚くする形で、コンポーネントが実際に組み合わさった状態の検証に価値を置くモデルです。React+TypeScriptのように、単体を細切れにモックすると実装詳細に密着してしまう環境では、トロフィー型が費用対効果で勝る場面があります。
使い分けの判断軸は「単体テストがどれだけ実装詳細に縛られるか」です。バックエンドのドメインロジックのように単体で意味のある単位が明確なら、下層を厚くするピラミッドが素直に効きます。UIコンポーネントの組み合わせが価値の中心なら、結合層を厚くするトロフィー型が候補です。両モデルの背景と選定基準はTesting Trophyの概要とKent C. Dodds氏の提唱背景で詳しく扱っています。まず自プロダクトの「意味のあるテスト単位」を見極め、形を後から選ぶのが順序です。
テスト戦略を内製で定着させる設計と外部知見・支援の使いどころ
ピラミッドの形は一度作って終わりではなく、機能追加のたびに配分が崩れます。CI/CDパイプラインで層ごとに実行タイミングを分け(プルリクごとに単体と一部結合、マージ後にE2E)、カバレッジや実行時間を継続的に観測して逆ピラミッド化を早期に検知する仕組みまで含めて、初めて戦略として定着します。テストを書く文化と観測の仕組みを社内に根づかせるところが、実装者にとっての本丸です。
とはいえ、既存システムの改修と並行してテスト基盤を整える体力が確保できないケースは少なくありません。既存コードの依存分離やCIへのテスト組み込み、内製チームへの設計移譲を伴走で進めたい場合は、Webシステムの保守運用・内製化支援で、テスト戦略の設計から運用定着までを一緒に組み立てられます。外注で作って終わりにせず、自走できる状態まで引き渡すことを前提に設計します。
テストピラミッドの層別配分・自動化戦略でよくある質問への回答
テストピラミッドを実務へ落とし込む際に、検索でよく問われる論点を5つ取り上げます。
テストピラミッドの単体・結合・E2Eの比率は必ず7:2:1にすべきですか?
いいえ。7:2:1(Googleの示した70:20:10)は目安であり、守るべき規範ではありません。判断の芯は「速く壊れにくい層に検証を寄せる」ことです。フロントエンド偏重なら結合層が厚くなり、ドメインロジック中心なら単体層がさらに支配的になります。比率を数値目標にすると水増しテストを生むため、優先順位(下層を厚く)だけを固定し、実際の配分はプロダクトの性質に合わせて決めてください。
テストピラミッドとテスティングトロフィーはどちらを選べばよいですか?
「意味のあるテスト単位」がどこにあるかで選びます。バックエンドのように単体で完結するロジックが多い場合はピラミッド(単体を厚く)が素直に効く形です。UIコンポーネントの組み合わせが価値の中心となるフロントエンドでは、結合層を厚くするトロフィー型が費用対効果で勝る場面があります。単体テストがモックだらけで実装詳細に密着し始めたら、トロフィー型への傾斜を検討する合図です。
アイスクリームコーン型になっているかはどう見分けますか?
3つの兆候で判断できます。CIの完走に数十分以上かかる、原因不明で赤くなるフレーキーなテストが常在する、失敗の原因究明に画面操作の再現が要る——このいずれかが出ていれば、E2Eが過多な逆ピラミッドを疑ってください。是正は、E2Eが見ている分岐のうちロジックで確認できるものを単体テストへ書き直し、E2Eを主要導線の確認だけに痩せさせる順で進めます。
E2Eテストは何本まで書いてよいですか?
本数の上限を数で決めるより、「落ちたらリリースを止める導線か」で選別します。ログイン・購入・申込みなど収益や登録に直結する数本に絞るのが基本です。入力バリデーションや表示分岐といった条件網羅はE2Eで抱え込まず、単体テストへ降ろします。E2Eが増え続けているなら、下層で守れる仕様を上層に押し上げていないか、設計を見直す時期です。
テストピラミッドはフロントエンドにも当てはまりますか?
当てはまりますが、層の厚みは調整が要ります。フロントエンドはコンポーネントの結合状態でこそ意味が出るため、単体を細かく刻むより結合層(コンポーネント同士を実際につなぐテスト)を厚めに取る構成が有効な場面があります。これがテスティングトロフィーの発想です。ピラミッドの「速い層に寄せる」思想は保ちつつ、フロントエンドでは結合層の比重を上げる、と捉えると齟齬なく運用できます。
関連記事
- 単体テストと結合テストはもう古い!Google流テストサイズとは?:テストサイズ(Small/Medium/Large)による層の再定義を判断ハブとして詳説
- リグレッションテスト(回帰テスト)とは?目的・範囲選定・自動化と実施判断を解説:ピラミッドの配分見直しと直結する回帰テストの範囲選定・自動化
- Testing Trophyとは何か?Kent C. Dodds氏提唱の新テスト指針の概要と背景を徹底解説:ピラミッドと対比される結合重視モデルの背景と選定基準
- Agent Skillsで運用する単体テストガイドラインの実務的意義と前提条件:ピラミッドの土台となる単体テストの運用ガイドライン化