テストの形 — ピラミッド・アイスクリームコーン・トロフィー・ハニカム
「どの種類のテストを、どれだけ書くべきか」という問いに対し、ソフトウェア業界は2000年代半ば以降、いくつもの図像を生み出してきた。Mike Cohnのテストピラミッド、Alister Scottのアイスクリームコーン、Kent C. Dodds のテスティングトロフィー、Spotifyのテスティングハニカム。各モデルの提唱者と主張の違いをたどり、この論争がなぜ今も決着していないのかを整理する。
「どの種類のテストを、どれだけ書くべきか」という問いに対して、ソフトウェア業界は2000年代半ば以降、いくつもの図像——ピラミッド、アイスクリームコーン、トロフィー、ハニカム——を生み出してきた。これらは単なる比喩ではなく、それぞれの時代の開発体制・アーキテクチャ・テストツールの制約を反映した、「その時点で最も費用対効果の高いテスト配分」についての主張である。本稿では、この議論がどう始まり、どう分岐し、なぜ今も決着していないのかを、各モデルの提唱者と主張の違いに沿って整理する。
テスト戦略が問題になるのは、テストが無限に書けるわけではないからだ。同じ振る舞いを検証するテストでも、粒度が細かいほど高速・安定・原因特定が容易になり、粒度が粗いほど「ユーザーにとっての価値」に近い代わりに遅く壊れやすくなる。この二律背反にどう配分するかという問いに、各モデルはそれぞれ異なる答えを出してきた。
テストピラミッドの起源 — Mike Cohn
テストピラミッドという概念の起源は、アジャイルコーチのMike Cohnにさかのぼる。Cohnは Lisa Crispin との対話の中で2003〜2004年ごろにこの図を描き、2009年の著書『Succeeding with Agile: Software Development Using Scrum』の中で「テスト自動化ピラミッド(Test Automation Pyramid)」として文章化した。Cohnのオリジナルの3層モデルは次の通りである。
- Unit Tests(最下層・最多)— 個々の関数・クラスを検証。高速
- Service Tests(中間層)— APIやサービス境界を検証
- UI Tests(最上層・最少)— GUIを通したエンドツーエンドの検証。低速・脆い
Cohnの主張の核心は「UI経由のテストは自動化コストが高く壊れやすいので、できる限り薄い層にとどめ、ロジックの大半は下の層で検証せよ」という配分の指針であり、単なる分類ではなく資源配分の戦略として提示された点が重要である。
Martin Fowlerによる普及と定式化
Cohnのモデルは元々アジャイルコミュニティ内の議論だったが、Martin Fowlerが2012年に自身のbliki に “TestPyramid” という短い記事を書いたことで、業界全体に広く知られる形になった。Fowlerは「ユニットテストを多く、統合テストを中程度、E2Eテストを少なく」という一般化された形でピラミッドを再定式化し、あわせて「アイスクリームコーン」という逆パターンにも触れて警鐘を鳴らした。
さらに2018年には、Fowlerのサイトに Ham Vocke(Thoughtworks)による “The Practical Test Pyramid” という長編記事が掲載され、抽象的な比喩だったピラミッドを、実際のコード例を伴う実践的なガイドへと肉付けした。この記事は「ピラミッドは概念としては正しいが、現場でどう実装するかの解像度が足りない」という不満に応える形で書かれている。
アイスクリームコーン — 逆ピラミッドという反面教師
ピラミッドと対をなす反面教師として広く引用されるのが「アイスクリームコーン(Ice-Cream Cone)」である。Watirコミュニティのコア貢献者だったAlister Scott が2012年のブログ記事 “Testing Pyramids & Ice-Cream Cones” でこの呼称を提示した。実際の組織でしばしば見られる、次のような逆転した配分を指す。
- 手動テストが最大量を占める
- UI自動化テストがそれに次ぐ
- 統合テストは中間程度
- ユニットテストが最も少ない
この形になると、テストスイートの実行に時間がかかり、失敗の原因特定が困難になり、フレーキー(flaky、不安定)なテストへの不信感からテストが形骸化するという悪循環に陥る。アイスクリームコーンは「意図して選んだ戦略」ではなく、テストを後付けで積み上げた結果として自然発生することが多く、その点でピラミッドとの対比は「設計されたものか、放置の産物か」という違いでもある。
テスティングトロフィーの登場 — Kent C. Dodds
2017年前後、JavaScriptコミュニティでReactなどのコンポーネント指向フロントエンドが主流になる中、Kent C. Dodds は “Write tests. Not too many. Mostly integration.” という発表・ブログ記事、および続く “The Testing Trophy and Testing Classifications” で「テスティングトロフィー(Testing Trophy)」を提唱した。前の記事で見たTesting Libraryも、同じDodds による設計である。
トロフィーは下から次の4層で構成される。
- 静的解析(Static) — 型チェック・Lint。土台
- ユニット(Unit)
- 統合(Integration) — トロフィーの中で最も広い層=最も投資すべき層
- E2E — 頂点、少数
Doddsの主張は「2012年当時と違い、モダンなテストツール(Jest、React Testing Library、後にはPlaywright等)によって、より広い範囲を検証するテストが以前ほど遅く・高価・脆くなくなった」という前提の変化に基づく。標語 “The more your tests resemble the way your software is used, the more confidence they can give you.”(テストがソフトウェアの実際の使われ方に近いほど、そのテストは高い確信度を与える)は、実装の詳細ではなくユーザーに見える振る舞いを検証すべきだという価値観を端的に表す。ピラミッドの否定というより、「どの層に一番投資すべきか」の力点をユニットから統合へ移す再重み付けである。
ハニカムモデル — マイクロサービスの視点
フロントエンドとは別の文脈で、Spotifyのエンジニアリングチームは2018年のブログ記事 “Testing of Microservices” で「テスティングハニカム(Testing Honeycomb)」を提示した。マイクロサービスアーキテクチャでは、サービス単体のロジックの複雑さよりも「サービス間の連携点」の複雑さの方が支配的になるという観察に基づき、ピラミッドの中間層(統合テスト)を最大の層に膨らませ、ユニットとUI(E2E)の両端を相対的に薄くする形を提案した。これはトロフィーと発想は近いが、フロントエンドの「コンポーネントの統合」ではなく「サービス間APIの統合」に焦点が当たっている点が異なる。
形状論争の背景にある構造変化
なぜ2012年のピラミッドが2017〜2018年に相次いで異議を唱えられたのか。背景には次のような環境変化がある。
- マイクロサービス化 — モノリスでは「ユニット」で守れたロジックが、サービス分割後は「サービス間の連携」に移動し、統合層の相対的重要性が増した
- フロントエンドのコンポーネント化 — React/Vue以降、UIは「個々の関数」よりも「レンダリングされた振る舞い」の単位でテストする方が価値が高くなった
- テストツールの高速化・安定化 — Cypress(2015年公開)、後のPlaywright(2020年公開)などにより、ブラウザテストの実行速度と決定性が2012年当時より大幅に改善した
- CI環境の並列化 — クラウドCIにより、以前は「遅すぎて避けるべき」だったテストの並列実行コストが下がった
つまり各モデルは普遍的な物理法則ではなく、「その時代の制約下で何に投資するのが最も割に合うか」という経済合理性の主張である。ツールが変われば最適配分も変わりうる、という前提を共有した上での意見の相違だと理解するのが正確である。
Googleの「テストサイズ」という代替の分類軸
ピラミッド系のモデルがいずれも「ユニット/統合/E2E」というテストの対象範囲(scope) で層を分けるのに対し、Googleは書籍『Software Engineering at Google』(Titus Winters, Tom Manshreck, Hyrum Wright編、O’Reilly、2020年)の中で、範囲ではなく実行時に許される資源制約によってテストを分類する「テストサイズ(test size)」という軸を提示している。
| サイズ | 実行環境の制約 | 典型的な特徴 |
|---|---|---|
| Small | 単一プロセス内で完結。ネットワーク・ディスク・別プロセスへのアクセス不可 | 高速・決定的。ほぼユニットテストに相当 |
| Medium | 単一マシン内で完結。localhost通信やディスクアクセスは許容 | DB・ローカルサービスを使う統合テストに相当することが多い |
| Large | 複数マシン・外部ネットワークへのアクセスも許容 | E2Eに近いが「範囲」ではなく「制約の緩さ」で定義される |
この分類の利点は、「これはユニットテストか統合テストか」という水掛け論を避け、CI上で「このテストはネットワークに触れてよいか」「並列実行時に他のテストと資源を奪い合わないか」という運用上の制約として機械的に検査できる点にある。範囲による分類と資源制約による分類は排他的ではなく、同じテストスイートに対する2つの異なる切り口として併用されることが多い。
コスト・速度・信頼性・決定性のトレードオフ
| 観点 | ユニット | 統合/契約 | E2E |
|---|---|---|---|
| 実行速度 | 非常に速い(ms) | 中速(秒) | 遅い(秒〜分) |
| 決定性(同じ結果を返すか) | 高い | 中程度(外部依存次第) | 低くなりやすい(環境・タイミング依存) |
| 書くコスト | 低い | 中程度 | 高い(セレクタ・待機・データ準備) |
| 保守コスト | 低い(実装非依存に書けば) | 中程度 | 高い(UI変更で壊れやすい) |
| 得られる確信度 | ロジック単位 | 連携部分 | ユーザー価値の連鎖全体 |
| 失敗原因の特定しやすさ | 容易 | やや容易 | 困難(どこで壊れたか探索が要る) |
この表が示す通り、単一の指標で「どの層が優れているか」は決まらない。戦略とは、この複数指標のどれを優先するかという価値判断そのものである。
モデル比較表
| モデル | 提唱者・出典 | 想定文脈 | 力点 |
|---|---|---|---|
| テストピラミッド | Mike Cohn(2009年、2003〜2004年頃発案)/Martin Fowler(2012年bliki) | アジャイル開発全般 | ユニットを最大量、UIを最小限に |
| アイスクリームコーン | Alister Scott(2012年) | 後付けでテストを積んだ現場 | 避けるべき反パターンとして提示 |
| テスティングトロフィー | Kent C. Dodds(2017年前後) | モダンJS/フロントエンド | 統合テストへの重点投資 |
| テスティングハニカム | Spotifyエンジニアリングブログ(2018年) | マイクロサービス | サービス間連携の検証を最大化 |
論争から学ぶこと
各モデルの対立から得られる実務的な教訓は、「唯一の正解となる形はない」という点に尽きる。戦略を立てる際に問うべきは次のような問いである。
- 自分たちのアーキテクチャで、複雑さが集中しているのはどこか(ロジック内部か、連携点か、UIか)
- 手元のテストツールは、どの層の実行を高速・安定にできる状態か
- チームがテストの失敗を信頼できているか(フレーキーテストの蓄積は、層に関わらず戦略を破綻させる)
- 変更頻度が高くリスクの大きい機能はどこか(そこに投資を厚くする)
ピラミッドを字面通り「UIテストを減らせばいい」と捉えるだけでなく、「なぜその形が提案されたのか」という背景の経済合理性を理解し、自分たちのアーキテクチャに合わせて形を選び直すことが、この論争から引き出せる最大の実務的価値である。
この記事から次の記事へ
テストの「配分」をめぐる論争を辿った。次の記事では視点を個々のテストの中身に移し、ユニットテストの設計とcontract(契約)という、テストの「粒度」よりもさらに内側にある設計原則を見ていく。