生成AIのおかげで、E2Eテストの「最初の1本」を作るハードルはかなり下がりました。
たとえば、ログインして商品を検索し、カートに追加するPlaywrightのコードであれば、要件を文章で渡すだけでもそれなりの形になります。SeleniumやCypressでも同じです。ノーコード系のツールなら、ブラウザ操作を記録したり、自然言語からテストを作成したりできます。
しかし、実際のプロジェクトで難しいのはテストコードを生成することではありません。
難しいのは、半年後もそのテストを信頼できる状態で運用することです。
- UI変更後も修正しやすいか
- CI上で再現性のある結果を出せるか
- 失敗時に原因を説明できるか
- iframeやShadow DOMを含む実画面を扱えるか
- ブラウザ実行環境を誰が管理するか
- テストを作った本人以外も保守できるか
本記事では、AI時代のテスト自動化を「テストを書く技術」ではなく、「信頼できるテストシステムを運用する技術」という視点で整理します。
1. 最初にテストすべきなのは、ログイン画面ではなく難しい画面
テスト自動化ツールの評価では、ログインフォームや単純なCRUD画面から試すことが多いと思います。
ただし、そのような画面で動くことは、実際のアプリケーションで使えることを意味しません。
現代のWebアプリケーションには、次のような要素が含まれます。
- Shadow DOMを使ったWeb Components
- 決済や認証フォームのiframe
- クロスオリジンの埋め込みコンテンツ
- チャット、分析、同意管理などの外部ウィジェット
- 動的に差し替えられるDOM
- SPAの画面遷移中だけ存在する要素
ツールを比較する場合は、簡単な画面ではなく、アプリケーション内で最も扱いにくい画面を使う方が現実的です。
How to Evaluate a Test Automation Platform for Shadow DOM, Iframes, and Embedded Third-Party Widgets では、こうした複雑なブラウザ構造を評価するときの観点が整理されています。
単に「iframe対応」「Shadow DOM対応」と書かれているだけでは不十分です。確認したいのは、失敗時も含めた一連の体験です。
- どのフレームを検索していたか分かるか
- Shadow Rootの内外を正しく移動できるか
- セレクタが壊れた理由を確認できるか
- 外部ウィジェットが遅延した場合に証拠が残るか
- テスト担当者が自分で修正できるか
機能一覧にチェックが付いていることと、実運用で保守できることは別問題です。
2. AIエージェントには「再試行」より「説明能力」が必要
AIテストエージェントには、失敗した操作を別の方法で再試行する機能があります。
たとえば、最初のロケータでボタンが見つからなかった場合に、表示テキストや周辺要素から別のロケータを生成して実行を続ける、といった動作です。
便利ではありますが、再試行後に成功しただけでは原因は分かりません。
- アプリケーションが一時的に遅かったのか
- DOMが変更されたのか
- テストデータが競合していたのか
- AIが別の要素をクリックしたのか
- 最初の失敗が本物の不具合だったのか
What to Log When an AI Test Agent Replays a Failed Run and Still Can’t Explain the Failure では、AIエージェントが失敗を再実行するときに残すべき情報がまとめられています。
最低限、以下は記録しておきたいところです。
{
"step": "Save buttonをクリック",
"expected": "編集内容が保存される",
"original_locator": "[data-testid='save']",
"observed": "element not found",
"fallback_locator": "role=button[name='Save']",
"fallback_reason": "同じラベルを持つbuttonを検出",
"confidence": 0.82,
"application_version": "2026.07.16",
"feature_flags": {
"new_editor": true
}
}
重要なのは、長い思考ログではありません。
「何を期待したか」「何を観測したか」「なぜ別の操作を選んだか」を短く追跡できることです。
自動修復が成功しても、根本原因が見えなければ、単に不具合を隠している可能性があります。
3. フレームワーク比較は、具体的な画面で行う
「Playwright、Selenium、Cypressのどれが一番良いか」という質問だけでは、実用的な答えを出すのは難しいです。
たとえば、動的テーブルをテストする場合、必要になるのは単純なクリックだけではありません。
- API経由で既知のデータを作成する
- テーブルの非同期更新を待つ
- 検索条件を入力する
- 対象行を位置ではなく内容で特定する
- 行内メニューを開く
- 更新結果をUIとAPIの両方で確認する
Endtest vs Cypress for Testing Dynamic Tables, Search Filters, and Inline Row Actions は、このような具体的なユースケースを使ってEndtestとCypressを比較しています。
コードによる細かい制御を優先するチームではCypressが扱いやすい場合があります。一方、QA担当者が直接テストを保守し、ブラウザ実行環境やレポートも含めて一つの製品で管理したい場合は、Endtestのような統合型プラットフォームが候補になります。
ここで大切なのは構文の好みだけで決めないことです。
AIによってコード生成コストは下がりましたが、生成されたコードの所有コストは残ります。
Selenium vs Cypress in the AI Era でも触れられているように、AIがPage Object、fixture、helper、assertionを生成してくれても、次の責任はチームに残ります。
- フレームワーク設計
- ライブラリ更新
- コードレビュー
- テストデータ管理
- CIの安定化
- ブラウザ環境の保守
- flaky testの調査
コードが速く作れることと、長期的に安く運用できることは同じではありません。
4. 状態の準備はAPI、ユーザー体験の確認はブラウザ
ブラウザテストを安定させる最も効果的な方法の一つは、すべてをブラウザで実行しないことです。
たとえば、アーカイブ済みプロジェクトの表示を確認したいテストで、以下を毎回UIから行う必要はありません。
- ユーザー作成
- ログイン
- プロジェクト作成
- 設定変更
- アーカイブ操作
検証対象が「アーカイブ後の表示」であれば、前提データはAPIで作り、ブラウザでは表示だけを確認できます。
How to Combine API Calls with Playwright Tests では、PlaywrightのAPIRequestContextを使って、セットアップ、認証、クリーンアップ、バックエンド検証を行う方法が紹介されています。
簡単な例です。
import { test, expect } from '@playwright/test';
test('archived project is shown in the archive list', async ({
request,
page,
}) => {
const createResponse = await request.post('/api/projects', {
data: {
name: `project-${Date.now()}`,
},
});
expect(createResponse.ok()).toBeTruthy();
const project = await createResponse.json();
const archiveResponse = await request.post(
`/api/projects/${project.id}/archive`
);
expect(archiveResponse.ok()).toBeTruthy();
await page.goto('/projects/archive');
await expect(
page.getByRole('row', { name: new RegExp(project.name) })
).toBeVisible();
});
判断基準はシンプルです。
操作そのものが検証対象ならUIを使う。状態だけが必要ならAPIを使う。
もちろん、サインアップ画面のテストでAPIからユーザーを作成してしまうと、検証対象を飛ばしてしまいます。
しかし、多くのE2Eスイートには、前提条件を作るためだけの不要なUI操作が大量に含まれています。それらをAPIに移すだけでも、実行時間とflaky率を大きく下げられます。
5. Feature Flagを使うなら、リリース方法そのものをテストする
現在のリリースでは、すべてのユーザーに同時に新機能を公開するとは限りません。
- 社内ユーザーのみ
- 特定の契約プランのみ
- 5%のユーザーのみ
- 特定地域のみ
- 新規アカウントのみ
このような段階的ロールアウトでは、完成した画面だけでなく、Feature Flagとロールバックの動作も検証する必要があります。
How to Build a Test Plan for Feature Flags, Rollouts, and Safe Reverts in Web Apps では、Feature Flagを含むテスト計画の考え方が紹介されています。
最低でも、以下の組み合わせは確認したいところです。
| 条件 | 期待結果 |
|---|---|
| Flag OFF | 旧UIが正常に動作する |
| Flag ON | 新UIが正常に動作する |
| 対象ユーザー | 新UIが表示される |
| 対象外ユーザー | 旧UIが維持される |
| セッション中に切替 | 不整合やデータ損失が起きない |
| ロールバック | 新しいデータを壊さず旧UIに戻れる |
また、UIの切り替えにアニメーションを使っている場合は注意が必要です。
CSS View Transitionsやアニメーション付きのルート変更では、要素がDOM上に存在していても、まだクリック可能ではないことがあります。
- 移動中
- 透明
- overlayに覆われている
- 古いページと新しいページの両方に存在する
- document自体が置き換えられている
How to Reduce Flaky Browser Tests Caused by Animated Route Changes and CSS View Transitions では、固定時間のsleepではなく、アプリケーションの意味のある状態を待つ方法が解説されています。
たとえば、次のような待ち方です。
await page.getByTestId('navigation-complete').waitFor();
await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible();
waitForTimeout(1000) を増やし続けるより、「画面遷移が完了したことを表す状態」をアプリケーション側に用意する方が安定します。
6. CI連携は、テストを起動するだけでは不十分
CircleCIからテストを実行できたとしても、それだけではCI連携が完成したとは言えません。
CIが判断できる必要があります。
- 期待したテストがすべて完了したか
- どのビルドを対象にしたか
- テスト失敗か、実行環境の障害か
- スクリーンショットや動画はどこにあるか
- デプロイを止めるべきか
How to Integrate Test Automation with CircleCI では、テストの起動、完了待ち、結果取得、終了コードへの反映までが説明されています。
Playwrightを直接実行する場合の基本形は次のようになります。
version: 2.1
jobs:
e2e:
docker:
- image: mcr.microsoft.com/playwright:v1.55.0-noble
steps:
- checkout
- run:
name: Install dependencies
command: npm ci
- run:
name: Run browser tests
command: npx playwright test
- store_artifacts:
path: playwright-report
- store_test_results:
path: test-results
workflows:
test:
jobs:
- e2e
外部のテストプラットフォームをAPIから呼び出す場合は、実行を開始するだけでなく、完了するまでポーリングし、最終結果をCIの終了コードに変換する必要があります。
テストを実行できることよりも、パイプラインがその結果を信頼して判断できることの方が重要です。
7. ブラウザ実行環境にも保守コストがある
E2Eテストが増えると、どこでブラウザを実行するかという問題が出てきます。
代表的な選択肢は次の二つです。
- Selenium Gridを自社運用する
- BrowserStackのようなクラウドを使う
Selenium Grid vs BrowserStack では、単純な料金比較ではなく、どの障害を自分たちで所有するかという観点で比較しています。
Selenium Gridを運用する場合、チームは以下を管理する可能性があります。
- ブラウザとDriverのバージョン
- Nodeの死活監視
- 並列数とスケーリング
- Dockerイメージ
- 動画やログの保存
- OSアップデート
- セキュリティ
- 障害時の復旧
BrowserStackのようなサービスでは料金が明確に発生しますが、その代わり、こうした運用の一部を外部化できます。
オープンソースのフレームワークが無料でも、実行環境まで無料になるわけではありません。
テスト自動化のコストを考えるときは、ライセンスだけでなく、ブラウザ基盤の保守時間も含める必要があります。
8. 手動リグレッションを置き換えるなら、テストケースの単純変換は避ける
よくある計画に、次のようなものがあります。
300件の手動テストケースを、そのまま300件の自動テストにする。
この方法では、古い手動プロセスをそのまま高コストな自動化に変換してしまう可能性があります。
先に考えるべきなのは、件数ではなくリスクです。
- 毎リリース確認すべき重要なユーザーフローは何か
- ブラウザ差分が問題になる部分はどこか
- APIレベルで確認した方がよい処理は何か
- 手動探索を残した方がよい領域は何か
- 誰がテストを保守するか
Endtest Buyer Guide for Teams Replacing Manual Regression on Fast-Changing Frontends では、変化の速いフロントエンドで手動リグレッションを置き換える際、初期作成速度よりも継続的な保守コストを重視しています。
Endtestのような統合型プラットフォームは、次のような機能を一つの環境にまとめています。
- 編集可能なE2Eテスト
- AIによる作成や修復
- クロスブラウザ実行
- APIステップ
- レポート、スクリーンショット、動画
- CI/CD連携
- QA担当者による直接保守
一方で、コードを完全に所有したいチームや、特殊な内部環境を持つチームでは、PlaywrightやSeleniumを使った自社フレームワークが適している場合もあります。
Best AI Test Automation Tools in 2026: My Practical Shortlist では、Endtestを含むAIテスト自動化ツールが、生成機能だけでなく、作成、実行、デバッグ、保守まで含めて比較されています。
ツール選定では、「AIでテストを書けるか」よりも、「チームがそのテストを運用し続けられるか」を見る方が現実的です。
9. フレームワークかプラットフォームか
すべてのチームに同じ正解があるわけではありません。
次のような条件では、PlaywrightやSeleniumを使った内製フレームワークが合理的です。
- テスト基盤を専門に担当するエンジニアがいる
- 特殊な環境や独自要件がある
- ソースコードの完全所有が必要
- ライブラリやブラウザ基盤の更新を継続できる
一方で、チームの目的が「テスト基盤を作ること」ではなく「回帰不具合を減らすこと」であれば、統合型プラットフォームの方が総コストを下げられる場合があります。
比較材料として、以下の動画も参考になります。
後者では、Endtest、Mabl、testRigor、Ghost Inspector、Reflect、TestMu AIなどが、実際の操作性を中心に比較されています。
まとめ
AIによって、テストコードの最初のドラフトは簡単に作れるようになりました。
しかし、テスト自動化の本当の難しさは別のところにあります。
- 複雑なDOM構造を扱う
- 失敗の証拠を残す
- AIの再試行を説明可能にする
- APIとUIの責務を分ける
- Feature Flagとロールバックを検証する
- CIが判断できる結果を返す
- ブラウザ基盤を保守する
- 作成者以外でもテストを修正できるようにする
最初のテストが動いたことは、まだスタート地点です。
本当に価値があるのは、数か月後もチームが結果を信頼でき、失敗を短時間で理解でき、通常のUI変更に追従できるテストシステムです。
AIはテスト作成を加速できます。
しかし、長期的に成功するかどうかは、テストの周辺にある運用コストをどれだけ減らせるかで決まります。
