🔬

Claude Codeのテスト自動化。システムテストは必要なのか

に公開

前回の記事で、/test-itスキル(結合テスト自動生成)を実プロジェクトで試した。specとの照合で漏れを見つけ、UTとITの境界も整理した。

次はシステムテスト(ST)だ。ITの上の層だからSTスキルを作ろう——そう思ってリサーチを始めたら、「ST」はE2Eに吸収されていた。 そしてE2E(End-to-End)テスト——ユーザーの操作フローを丸ごとブラウザで再現するテスト——の正しいスコープは、自分が思っていたものと全く違った。

STはE2Eに吸収されていた

ITの次はST。自然な発想だった。ISTQB(International Software Testing Qualifications Board、ソフトウェアテストの国際資格団体)の教科書的な4層モデル(UT → IT → ST → 受入テスト)を頭に入れていたから。

でも「STとは何か」を真面目にリサーチしたら、話が変わった。

ISTQBの定義ではSTとE2Eは別物だ。STは「単一システムの要件検証」、E2Eは「複数システム横断のワークフロー検証」。ここまでは教科書通り。

ところが、実務で使われているテスト戦略モデルを並べてみると景色が違う。

モデル 提唱者 層構成 STの扱い
Testing Pyramid Mike Cohn (2009) Unit > Service > UI Service層にST含む
Testing Trophy Kent C. Dodds (2018) Static / Unit / Integration / E2E STは存在しない
Testing Diamond 複数 (2020s) Unit / Integration / E2E STは存在しない
Testing Honeycomb Spotify (2018) Impl Detail / Integration / Integrated STは存在しない

Pyramid以外の全モデルが「ST」を独立した層として持っていない。STの役割はE2Eに吸収されている。

Martin Fowlerの言葉が刺さった。「テストカテゴリについて議論する際は、相手がその言葉で何を意味しているかを掘り下げよ」。用語の定義争いより、テストが何を検証するかに集中すべきだと。

結論: /test-stではなく/test-e2eとして設計する。

BDD/Gherkinは要らなかった

E2Eテスト生成で最初に思い浮かぶのはBDD(Behavior-Driven Development)。Given/When/Then形式でシナリオを書き、Cucumber等のフレームワークでテストコードに変換する流れだ。

でも調べたところ、BDDフレームワーク自体が衰退期にあった。

  • SpecFlow: 2024年にEOL(End of Life)。開発終了
  • Cucumber: SmartBearが手放し、コミュニティ主導に。停滞気味

なぜ衰退したのか。リサーチで見つけた金融機関の事例が象徴的だった。Gherkinのステップ定義メンテナンスに開発工数の3倍が消費され、最終的に放棄された。 Feature → Step Definition → Page Objectの3層を維持するコストが、テスト自体の価値を上回ってしまう。

そもそもBDD/Gherkinの価値は「人間が読める仕様」にあった。でも自分のワークフローではspec.md自体がGiven/When/Then形式で書かれている。LLMはspecを直接理解できるから、Gherkinという中間翻訳層を挟む理由がない。

spec.md → LLM直接変換 → Playwrightテストコード。 この1ステップが2025-2026年の最適解だと判断した。

カンニング防止をE2Eでどう実現するか

10回目の記事で書いた「カンニング防止」。AIにテストを書かせるとき、実装コード(src/)を見せると実装に寄り添ったテストになり、仕様との乖離を見逃す問題だ。

/test-itではClaude CodeのTask tool(別コンテキストでサブタスクを実行する機能)を使い、specだけ渡して実装コードを見せない1段階方式で解決した。

E2Eはブラウザ操作が必要なので、同じ方式は使えない。セレクタ情報(画面のどのボタンを押すか等)がなければテストが書けない。かといってsrc/を見せたらカンニング防止が崩れる。

2段階アーキテクチャで解決した。

Step 1(メインコンテキスト): Playwright MCP(ブラウザ操作用のツール)でアプリを探索し、画面構造やボタン・入力欄のセレクタ情報をpage-map.mdに書き出す。

Step 2(Task tool): spec + page-map.mdだけを渡してテストコードを生成。src/は見えない。

AIがテスト生成時に見ていいもの、見てはいけないものを明確に分けた。見せないのはsrc/(実装コード)だけ。 それ以外の情報源でテストに必要な知識を渡す。

  • spec(仕様書)
  • page-map.md(セレクタ情報)
  • ARCHITECTURE.md(設計ドキュメント)
  • DOM / アクセシビリティツリー

最初の設計は間違っていた

ここまでで「カンニング防止」と「ブラウザ操作」の両立はできた。/test-itと同じノリで「specの全User Story(US)と全Edge Case(EC)をE2Eでカバーしろ」とスキルに書いた。

これが間違いだった。

E2Eには、ITにはない3つの問題がある。

1. 壊れやすさ(Flaky Tests)

ITはインプロセスで動く。ネットワークもブラウザも介在しない。E2Eは違う。ブラウザの起動、ネットワーク通信、アニメーション、非同期ロード——全部が変数になる。バグがないのにテストが落ちる。いわゆるFlaky Test(不安定なテスト)だ。

「たまに落ちるテスト」が混ざると、チームはテスト結果を信用しなくなる。

2. メンテナンスコスト

UIが変わるたびにセレクタの更新が発生する。ボタンのラベル変更、フォーム構造の変更——その都度テストコードに手を入れる必要がある。先述の金融機関事例では、ステップ定義のメンテナンスが開発の3倍のコストに膨らんでいた。

3. スコープ肥大

全US/ECをE2Eでカバーしようとすると、テストスイートが肥大化する。巨大なE2Eスイートは実行が遅く、壊れやすく、直す気力も湧かない。行き着く先は「全部無視してデプロイ」だ。

E2Eは煙テストだった

じゃあE2Eで何をテストするのか。

煙テスト(Smoke Test)。 アプリの最も重要な経路が動くことだけを確認する。ログインできるか。メインの操作フローが通るか。決済が完了するか。「煙が出ていないか」を確認するテストだ。

修正後のスコープルールはこうなった。

対象 E2Eでテストする?
クリティカルパスのP1(最優先)User Story する
P2以下のUser Story しない。ITでカバー
Edge Case しない。ITでカバー
非機能要件(性能、セキュリティ) しない。専用ツールで

Edge CaseはITに任せる。 /test-itはインプロセスで動くからFlaky Testにならないし、実行も速い。E2Eは「メインの道が通るか」だけに集中させる。

テストデータと環境の4課題

スコープを絞っても、E2Eには環境まわりの課題が残った。

課題 内容
テストデータ フロントエンド(localStorage等)とバックエンド(DB等)の2層をどうセットアップするか
認証フロー ログインの方式はプロジェクトごとに違う。storageStateの事前保存等
page-mapの鮮度 UI変更後にセレクタ情報が古くなる。いつ再探索するか
APIモック方針 外部APIをモックするか実際に叩くかはプロジェクト依存

これらは実装の詳細だから、src/を見ないと解決できない——と最初は思った。

でもよく考えると、認証方式やデータ層の構成は設計ドキュメント(ARCHITECTURE.md)に書いてある情報だ。実装コードを直接見なくても、設計レベルの情報があればテストのセットアップは書ける。

ARCHITECTURE.mdをTask toolに渡す対象に追加。 カンニング防止を維持しつつ、環境情報を渡す方法が見つかった。

テスト戦略の全体像

ここまでで、AI開発フロー全体のテスト戦略が整理できた。

各層が何を検証するか。

テスト層 誰が実行 何を検証するか
UT Agent Teams内のQA担当 1モジュール単体の振る舞い。障害の切り分け
IT /test-itスキル モジュール間のデータ受け渡し。specの全US/EC
E2E /test-e2eスキル クリティカルなユーザーフロー(煙テスト)
コードレビュー /reviewスキル コード品質、設計の一貫性
モンキーテスト 人間 想定外の操作、AIが見逃すUXの違和感

人間がやるのはモンキーテストだけ。 「適当に触ってみて変なところがないか」——これはAIが最も苦手で、人間が最も得意な領域だ。

/test-itとの設計比較

最後に、/test-it(IT)と/test-e2e(E2E)の設計を並べてみる。

/test-it (IT) /test-e2e (E2E)
入力 spec + plan spec + page-map + ARCHITECTURE.md
スコープ specの全US/EC クリティカルパスのP1 USのみ
Edge Case カバーする やらない(ITに任せる)
隔離方式 Task tool 1段階 2段階(MCP探索 → Task toolでテスト生成)
カンニング防止 src/を見せない src/を見せない。page-map経由でUI情報だけ渡す
テストランナー Vitest / Jest Playwright Test
実行環境 インプロセス ブラウザ
Flaky Testリスク 低い 高い(だからスコープを絞る)

共通しているのは「src/を見せない」「specを基準にする」という原則。違うのはスコープの考え方だ。ITは網羅性、E2Eは選択と集中。

まとめ

学び 内容
STという層は要らない Testing Trophy/Diamond/Honeycombのどれも「ST」を持たない。E2Eに吸収されている
E2Eは煙テスト 全仕様をカバーしようとすると壊れる。クリティカルパスだけ。Edge CaseはITに任せる
カンニング防止はE2Eでも維持できる 2段階アーキテクチャ(MCP探索 → Task toolでテスト生成)でsrc/を見せずにブラウザテストが書ける
BDD/Gherkinは不要 LLMがspecから直接テストコードを生成できる。中間翻訳層のメンテコストを払う理由がない

「ITの次はST」という教科書的な発想から始めて、リサーチで軌道修正し、最初の設計ミス(全仕様E2Eカバー)も修正した。テスト設計は「何をテストするか」より「何をテストしないか」の判断が難しい。 E2Eでは特にそうだった。

Discussion