1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Playwright Trace ViewerでAI生成E2Eテストの失敗原因を10分で絞る — 4証拠の読み順

1
Posted at

Playwright Trace ViewerでAI生成E2Eテストの失敗原因を10分で絞る — 4証拠の読み順

更新日: 2026-07-26

AIにE2Eテストを書いてもらった。ローカルでは通った。でもCIでは赤い。もう一度実行すると、今度は通る。

そこでエラーログをAIへ渡したら、timeout: 60000を足す修正が返ってきた。

でも、ちょっと待ってください。その修正で、本当に原因は消えたんでしょうか。

結論から言うと、コードを直す前にtraceを残し、Action、DOM snapshot、Network、Consoleの4証拠を順番に読みます

AIは証拠の比較、原因仮説の整理、最小修正案の作成をかなり速くできます。一方で、何が正しい仕様か、traceをどこまで共有してよいか、どの修正を採用するかは人間が判断します。

ログの最後の1行だけで事件を解こうとしない。現場に残った証拠を、時間順に見る。

僕はこの調査手順を 「証拠の読み順」 と呼びます。

この記事では、まず10分で意図的な失敗traceを作り、Trace Viewerを開きます。そのあと、4証拠の読み方、AIへ渡すプロンプト、CIへ入れる設定、効かない条件までつなげます。

最初に4つの用語だけ

E2Eテスト は、ユーザーがブラウザで行う操作を、入口から結果まで通して確かめるテストです。ログイン、検索、購入など、複数の画面やAPIをまたぐ流れを検査します。

trace は、テスト中に何が起きたかを後からたどるための記録です。PlaywrightのTrace Viewerでは、操作、DOMの状態、通信、Consoleなどを時間順に確認できます。

retry は、失敗したテストをもう一度実行する仕組みです。Playwrightは、最初から通ったテストをpassed、最初は落ちたが再実行で通ったテストをflaky、再実行しても落ちたテストをfailedとして分けます。

locator は、ボタンや入力欄など、操作したい要素を見つけるための表現です。getByRolegetByLabelのように、ユーザーから見える役割や名前で探せます。

ここで大事なのは、retryで通ったことを「直った」と考えないことです。

一度落ちてから通ったなら、それは成功の証明ではなく、条件によって結果が変わる証拠 です。

人間、AI、Playwrightの役割を先に分ける

担当 任せること 任せないこと
人間 期待仕様、許容時間、機密境界、修正承認 trace内の大量比較
AI 証拠の要約、仮説の順位付け、修正候補、再発防止案 仕様の最終決定、traceの無断外部送信
Playwright 操作記録、DOM snapshot、通信、Console、再実行分類 業務上どちらが正しいかの判断

AIに向いているのは、たくさんの観測事実を並べ、共通点と差分を探す仕事です。

人間が持つべきなのは、「検索結果は0件でも正常なのか」「3秒を超えたら失敗なのか」「この通信内容を外部サービスへ渡してよいか」という判断です。

つまり、AIに原因を当ててもらうのではなく、AIが比較できる証拠を人間が用意する。この順番です。

10分の初回成功: 失敗traceを自分で開く

まずは、外部サイトにもバックエンドにも接続しない最小例で試します。わざと失敗させるので、赤くなって正解です。

tests/search.spec.tsを作ります。

import { test, expect } from '@playwright/test';

test('商品検索の結果件数を表示する', async ({ page }) => {
  await page.setContent(`
    <main>
      <button type="button">検索</button>
      <div id="result">0件</div>
    </main>
  `);

  await page.getByRole('button', { name: '検索' }).click();

  // 画面は「0件」なので、ここは意図的に失敗する
  await expect(page.locator('#result')).toHaveText('3件');
});

次の2コマンドを実行します。

npx playwright test tests/search.spec.ts --trace on
npx playwright show-trace test-results/**/trace.zip

Trace Viewerが開いたら、失敗したexpect.toHaveTextを選んでください。期待値は3件、実際のDOMは0件です。

これで最初の成功です。

テストは落ちています。でも、「なぜ落ちたかを目で選べる状態」まで進みました。理解した、ではなく、証拠が動いた。

なお、--trace onは各テストのtraceを記録するため、ローカルの少数テストで調査する時に向いています。Playwright公式は、CIではすべての実行で常時記録するより、最初のretryで記録する設定を案内しています。そこは後半で設定します。

4証拠はAction → DOM → Network → Consoleの順で読む

Trace Viewerには情報が多いです。最初から全部を見ると、むしろ迷います。

そこで読み順を固定します。

  1. Actionで「どこから失敗したか」を決める
  2. DOM snapshotで「その瞬間に何が見えていたか」を確かめる
  3. Networkで「必要なデータが届いたか」を確かめる
  4. Consoleで「画面側の例外や警告」を確かめる

順に見ていきましょう。

証拠1: Actionで最初のズレを探す

Actionには、clickfillexpectなど、テストが実行した操作が並びます。

ここで見るのは、最後に赤くなった行だけではありません。赤い行より一つ前の操作が、期待どおり完了しているか を見ます。

たとえば、次の失敗は全部「結果が表示されない」に見えます。

  • 検索ボタンを別の要素が覆っていて、clickできなかった
  • clickは通ったが、検索APIを呼んでいなかった
  • APIは成功したが、DOMの表示更新が遅れていた
  • DOMは更新されたが、テストのlocatorが古い文言を探していた

エラーログの最後だけを見ると、どれもtimeoutに見えます。でも、最初にズレたActionは違います。

Playwrightのlocator actionは、要素が表示されているか、安定しているか、イベントを受け取れるか、有効かなどを確認してから操作します。clickで止まったなら、まず「待ち時間が短い」より、Actionの詳細と直前状態を見る方が筋がええんです。

Actionで見る3点

  • 失敗したActionの名前
  • 開始から失敗までの時間
  • 直前に成功したActionと、その時の画面

ここで原因がlocatorの取り違えだと分かったら、timeoutを延ばしても直りません。間違った住所で、配達を長く待つようなものです。

証拠2: DOM snapshotで「その瞬間」を見る

DOMは、ブラウザが持っている画面構造です。Trace Viewerのsnapshotを使うと、テストがそのActionを行った時点の状態を前後にたどれます。

スクリーンショットは見た目を確認するのに便利です。一方、DOM snapshotでは、要素の役割、属性、文言、構造をより詳しく確かめられます。

たとえばgetByRole('button', { name: '検索' })が失敗した時、次を確認します。

  • 本当にbuttonとして存在するか
  • 名前が「検索」ではなく「商品を検索」へ変わっていないか
  • disabledになっていないか
  • 同じ名前のbuttonが2つ存在しないか
  • dialogやoverlayの下に隠れていないか

AIが生成したテストでは、CSS classやDOM階層へ強く依存するlocatorが混ざることがあります。

// 壊れやすい例
await page.locator('div:nth-child(3) > button.btn-primary').click();

// ユーザーの認識に近い例
await page.getByRole('button', { name: '検索' }).click();

ただし、後者へ変えればいつでも正しいわけではありません。同名buttonが複数あるなら、画面側のアクセシビリティ設計か、検索範囲の設計を人間が決める必要があります。

AIにはlocator候補を出してもらう。どのUI表現が仕様として安定しているかは、人間が決める。

証拠3: Networkで「届かなかった」を分ける

画面に結果が出ない時、DOMだけを直し続けても治らない場合があります。

Networkでは、ブラウザが送ったrequestと受け取ったresponseを確認します。

見る順番は次の通りです。

  1. 期待したAPI requestが発生したか
  2. statusは成功か、4xxか、5xxか
  3. responseは期待した形か
  4. 異常に時間がかかっていないか
  5. retry前後で内容が変わっていないか

たとえば、検索APIが500を返しているなら、locatorの修正では直りません。401なら認証状態、429ならレート制限、200なのに空配列ならtest dataや環境の問題が候補になります。

ここで大事なのは、statusだけで断定しないことです。

200でもエラー情報を返すAPIはありますし、404が「商品なし」という正常仕様の場合もあります。業務上の期待は人間が定義します。

また、request/responseにはtoken、cookie、個人情報、テスト用アカウント情報が含まれる可能性があります。trace.zipを、そのまま外部AIや公開チャットへ投入しないでください

必要な箇所をマスクした要約へ変換するか、組織で許可された閉じた環境だけを使います。

証拠4: Consoleで画面側の例外を探す

通信が成功し、DOMも途中まで更新されているのに画面が完成しない。

そんな時はConsoleを見ます。

よくある候補は次です。

  • TypeErrorなどのJavaScript例外
  • hydrationの不一致
  • 未処理Promise rejection
  • feature flagや環境変数の不足
  • アプリが出している独自エラーログ

ただし、Console warningが1件あるから、それが原因とは限りません。広告、拡張機能、開発用warningなど、失敗と無関係なノイズもあります。

Actionの時刻とConsoleの時刻を照合し、失敗直前に何が起きたかを見ます。

相関と因果は別物。

Consoleは容疑者一覧であって、判決ではありません。

原因を5分類すると修正が小さくなる

4証拠を読んだら、原因候補を次の5つへ分類します。

分類 代表的な証拠 修正の方向
locator ActionとDOMが不一致 安定したrole/name/test idへ変更
test data API成功だが期待データなし テストごとのデータ作成・掃除
application Network成功後にConsole例外 本体コード修正と回帰テスト
network 4xx/5xx/遅延 mock、契約テスト、環境修正
environment CIだけ設定・時刻・locale差 実行条件の固定と明示

分類の目的は、きれいなラベルを付けることではありません。

修正範囲を小さくすること です。

locatorの問題なら、アプリ全体のtimeoutを延ばさない。test dataの問題なら、UIを無理に待たせない。environmentの問題なら、テスト本文へ謎の分岐を足さない。

原因と修正の層をそろえると、未来の手戻りが減ります。

AIへ任せるプロンプト1: 仮説を3件に絞る

trace全部ではなく、機密を除いた観測事実を渡します。

あなたはE2Eテスト調査の補助者です。
次の観測事実だけを使い、原因仮説を最大3件に絞ってください。

各仮説に次を付けてください。
- 根拠となる観測事実
- その仮説を否定できる反証条件
- 次に1つだけ見る証拠
- locator / test data / application / network / environment の分類

証拠がない内容は「推測」と明記してください。
期待仕様を勝手に変更しないでください。

ポイントは「原因を当てて」ではなく、反証条件と次の証拠を要求すること です。

AIの答えを結論ではなく、調査順へ変えます。

AIへ任せるプロンプト2: 最小修正を比較する

期待仕様は変えません。
固定sleep、無条件retry、全体timeout延長を追加せず、
観測された原因を除く最小修正案を2案ください。

各案について次を示してください。
- 変更ファイルと変更理由
- 副作用
- 再発を検知するassertion
- 採用前に人間が確認すること

証拠で支えられない修正は提案しないでください。

禁止事項を先に置くと、「とりあえず待つ」という対症療法が混ざりにくくなります。

もちろん、timeout変更が正しい場合もあります。たとえば業務上30秒かかる処理を5秒で失敗させているなら、expect timeoutの見直しは候補です。

ただし、Playwrightにはテスト全体のtimeoutとexpectのtimeoutが別にあります。公式ドキュメントでは、既定のtest timeoutは30秒、expect timeoutは5秒です。どちらを変えるかは、「何を待っているか」を確認してから決めます。

AIへ任せるプロンプト3: 再発防止をチーム資産にする

次の失敗記録から、再発防止案を作ってください。

出力を分けてください。
1. Playwright設定で自動化すること
2. テストコードへ追加すること
3. アプリ側で直すこと
4. 人間がレビュー時に判断すること
5. traceに残してはいけない機密

実行済みの確認と、未実行の提案を明記してください。

修正コードだけでなく、次に同じことが起きた時の観測手段まで残します。

コピーできるコードより、途中でやめない更新の仕組み。そこまで作って、初めてチームの資産になります。

CIでは最初のretryだけtraceを記録する

ローカル調査では--trace onが分かりやすいですが、CIの全テストで常時traceを取ると、実行時間と保存容量が増えます。

Playwright公式が案内する基本形は、最初のretryでtraceを記録する設定です。

import { defineConfig } from '@playwright/test';

export default defineConfig({
  retries: process.env.CI ? 1 : 0,
  reporter: [['html', { open: 'never' }]],
  use: {
    trace: 'on-first-retry',
  },
});

retryを使わず、最初の失敗を残したいチームはretain-on-failureも選べます。

ここで気をつけたいのが、retries: 1を「一回落ちても通れば合格」と運用しないことです。Playwrightはretryで通ったテストをflakyとして区別します。

チームでは少なくとも次を決めておくと迷いが減ります。

  • flakyをPRの合格に含めるか
  • trace artifactの保存期間
  • traceを閲覧できる人
  • 認証情報や個人情報を含むテストの扱い
  • 同じテストが何回flakyになったら修正対象にするか

retryは証拠を取る機会です。失敗を見えなくする消しゴムではありません。

traceを安全に扱う

Playwrightの公式CIガイドも、trace、HTML report、Console logなどのartifactには、テストユーザーの資格情報、access token、画面やソースコードなどが含まれ得ると注意しています。

安全ルールはシンプルです。

  1. 本番アカウントでE2Eを実行しない
  2. traceを公開artifactにしない
  3. 信頼済みの保存先と閲覧権限を使う
  4. 保存期間を必要最小限にする
  5. 外部AIへ渡す時は組織ルールを確認し、必要箇所だけ匿名化する

AIへ渡すこと自体が悪いわけではありません。

問題は、何が入っているか確認せず、zipを丸ごと渡すことです。

共有範囲を決めるのは人間。比較と要約を速めるのはAI。この境界を崩さないようにします。

この方法が効かない条件

Trace Viewerは、ブラウザから観測できる失敗に強いです。

でも、次の原因はtraceだけで確定できないことがあります。

  • 外部サービス内部の障害
  • queueや非同期workerの内部状態
  • databaseのlockやreplication遅延
  • 仕様書と実装のどちらが正しいか
  • ユーザー環境固有の端末・ネットワーク問題

この場合は、traceの時刻、request ID、テスト名を起点に、サーバーログ、分散trace、メトリクス、監査ログへ進みます。

つまり、この方法は万能な原因特定法ではありません。

ブラウザの外へ原因がある時に、次の観測場所を選ぶための入口 です。

また、テストが単純でローカルですぐ再現できるなら、Trace Viewerを開かずエラーメッセージだけで十分な場合もあります。すべての失敗へ重い調査を持ち込む必要はありません。

見分け方は、「同じ条件で再現するか」です。

毎回同じ行で同じ理由なら、まず通常のデバッグ。CIだけ、たまに、retryで結果が変わるなら、traceを残す価値が上がります。

今日10分でやること

最初からチーム全体へ導入しなくて大丈夫です。

今日やることは一つだけ。

手元の失敗テストを1本、--trace onで実行し、赤いActionと直前のDOMを開く。

原因を直せなくてもかまいません。「次にNetworkを見る」「locatorを見直す」と選べたら、推測ゲームからは一歩抜けています。

AIがコードを書く速度は、これからも上がると思います。

せやからこそ、人間の仕事は、生成された答えを眺めることから、正しい証拠を集め、判断の境界を設計することへ移っていく。

未来の自分が、CIの再実行ボタンを何度も押さずに済む。今日の小さなtraceが、その時間を省いてくれます。

動作確認

  • 最小テストとplaywright.config.tsはPlaywright 1.62.0で実行しました。
  • Expected: "3件" / Received: "0件"で意図どおり失敗し、trace.zipが生成されることを確認しました。
  • CI artifact設定は環境依存のため、この記事では動作未確認です。

参考リンク(一次情報・2026-07-26確認)

生成AI活用エンジニア&3児のパパ。AI×開発の実践知を毎日発信しています → X

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?