0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AIが自動でE2Eテストを計画・実装・修正する Playwright Agents × Claude Codeで E2Eテスト自動化の検証(導入編)

0
Last updated at Posted at 2026-09-28

はじめに

AIの登場で開発スピードは大きく上がりました。
一方で、AIが書いたコードの品質までは保証してくれません。
そのため、QA(品質保証)の役割はむしろ大きくなっていますが、
すべてを手動でテストするのは現実的でないです。

そこで今回は、AIエージェントを使ってE2Eテストをどこまで自動化できるのかを検証してみました。

この記事は導入編です。Playwright Agents を Next.js(App Router)のプロジェクトに入れて、エージェントが動ける状態にするまでをまとめています。
実際にテストを計画・生成・修正させた結果は、実践編として別の記事にまとめる予定です。

Playwright Agentsとは

2025年10月(Playwright v1.56)に登場した E2E テスト(エンドツーエンドテスト)を自動化する機能です。

従来、E2E テストの作成には以下のような課題がありました:

  • テストケースの洗い出しに時間がかかる
  • テストコードの実装が難しく、手間
  • UI 変更のたびにテストを書き直す

Playwright Agents では、これらの課題を3つのAIエージェントが分担して解決します。テストの計画から実装、修正までをAIに任せることで、
開発者は「どうやってプロダクトを伸ばすか、どういう機能を作るべきか」など
本来エンジニアとして1番大事な部分に集中できます。

前提として

  • Next.js(App Router)
  • Playwright v1.57.0
  • Claude Code から使う
  • ハーネスエンジニアリングの設計で、.claude/ 配下に agents/(サブエージェント)や rules/ を置いている

ハーネスや .claude/agents が分からなかったら以下の記事を読んでください。

「AIが書いたから大丈夫」が一番危ない😱 ハーネスエンジニアリング完全ガイド

導入で使ったPR

3つのエージェントの概念

スクリーンショット 2026-09-27 23.56.45.png

Planner(計画)

アプリを実際に操作しながら画面を探索し、テスト計画をMarkdownで作成します。計画は specs/ 配下に出力されます。

Generator(実装)

Plannerが作った計画をもとに、実際にブラウザでセレクタや動作を確認しながらPlaywrightのテストコードを生成します。

Healer(修正)

失敗したテストを再実行してUIを調べ、セレクタの変更などに合わせてテストを修正します。

3つのエージェントの違い

定義ファイルを見ると、使えるツールが違います。

エージェント ファイルの書き方 seed を実行するか
Planner planner_save_plan(MCP)で計画を保存 する(planner_setup_page)
Generator generator_write_test(MCP)でテストを保存 する(generator_setup_page)
Healer Edit / Write で直接テストを書き換える しない(test_run で既存テストを実行)

ファイルを直接書き換えられるのは Healer だけです。後で説明しますが、ここがカスタマイズのポイントになります。

このPJの構成

init-agents 実行後、Playwright Agents 関連のファイルはこうなります。

.
├── .claude/
│   ├── agents/
│   │   ├── playwright-test-planner.md    # 追加(init-agents)
│   │   ├── playwright-test-generator.md  # 追加(init-agents)
│   │   ├── playwright-test-healer.md     # 追加(init-agents)
│   │   └── code-review.md など            # 既存のサブエージェント
│   └── rules/
│       ├── testing-unit.md               # testing.md を分割
│       └── testing-e2e.md                # testing.md を分割
├── .mcp.json                             # 追加(playwright-test MCP サーバー)
├── e2e/
│   ├── helpers/auth.ts                   # 既存(createTestUser / signup など)
│   ├── global-teardown.ts                # 既存(テストユーザーの削除)
│   ├── seed.spec.ts                      # 追加(init-agents)
│   └── *.spec.ts                         # 既存のE2Eテスト
├── specs/
│   └── README.md                         # 追加(テスト計画の置き場)
└── playwright.config.ts                  # testDir: './e2e'

init-agentsを実行

Claude Code 向けに初期化します。

npx playwright init-agents --loop=claude

するとこんな感じで出てきます。

npm notice run next-app-router-share-app@0.1.0 npx
npm notice run 'playwright' init-agents --loop=claude
 🎭 Using project "" as a primary project
 📝 specs/README.md - directory for test plans
 🌱 e2e/seed.spec.ts - default environment seed file
 🤖 .claude/agents/playwright-test-generator.md - agent definition
 🤖 .claude/agents/playwright-test-healer.md - agent definition
 🤖 .claude/agents/playwright-test-planner.md - agent definition
 🔧 .mcp.json - mcp configuration
 ✅ Done.

playwright.config.ts の testDir(このPJでは ./e2e)を読んで、seed ファイルを e2e/ に置いてくれます。

.mcp.json にはこれが追加されます。エージェントはこの MCP サーバー経由でブラウザを操作します。

.mcp.json
{
  "mcpServers": {
    "playwright-test": {
      "command": "npx",
      "args": ["playwright", "run-test-mcp-server"]
    }
  }
}

Claude Code を再起動

起動時に playwright-test MCP サーバーの承認を求められるので、承認します。

seed を書き換える

seed は、Planner と Generator が作業を始める前に実行されるテストです。ログインなど、毎回必要な準備をここに書きます。

このPJでは、新規ユーザーを登録してログイン済みの状態にしました。

e2e/seed.spec.ts
import { test } from '@playwright/test';
import { createTestUser, signup } from './helpers/auth';

test.describe('Test group', () => {
  test('seed', async ({ page }) => {
    // Playwright Agents が作業を始める前に、ログイン済みの状態を用意する
    // このログイン状態は後続のテストには引き継がれないため、
    // 生成するテストでも各テストの冒頭で createTestUser() + signup() を行う
    const user = createTestUser();
    await signup(page, user);
  });
});

ポイントは3つです。

  • login() ではなく signup() を使う:createTestUser() はまだ登録されていないユーザーを作るので、login() ではログインできません
  • メールアドレスは test- 始まり:e2e/global-teardown.ts がテスト後に test- 始まりのユーザーを削除するので、DB にゴミが残りません
  • seed のログイン状態は後続のテストに引き継がれない:生成されるテストでも、各テストの冒頭で createTestUser() + signup() を行う必要があります

storageState でログイン状態を共有する方法もありますが、今回は不採用にしました。既存の auth.spec.ts が「未ログイン」を前提にしているためです。実践では、未ログインから始めようと思います。

以下のコマンドで seed を実行します。DBとdevサーバーの起動も忘れずに(playwright.config.ts に webServer を設定していないため、自分で起動します)。

# DB だけ起動
docker compose up db -d

# 別ターミナルで dev サーバーを起動
npm run dev

# seed を実行
npx playwright test e2e/seed.spec.ts

実行後、レポートで動いたか確認します。

npx playwright show-report

seed が通るとこんな感じの画面になります。

スクリーンショット 2026-09-28 1.15.29.png

つまずいたところ

seed を通すまでに、いくつかハマりました。

症状 原因 対処
ERR_CONNECTION_REFUSED dev サーバーが起動していない npm run dev
waitForURL が10秒でタイムアウト DB が起動していない / 空で、signup が失敗している DB を起動する。タイムアウトを延ばしても直らない
3000番ポートが衝突 docker compose up -d で app サービスも起動していた docker compose up db -d で DB だけ起動
signup が失敗する DB にテーブルがない npx prisma migrate dev

特に2つ目は、タイムアウトに見えて実は signup の失敗なのが気がつかなかったです。

生成されたエージェント定義をそのまま使わない

init-agents が生成したエージェント定義を、CodeRabbitによるPRレビューで3か所修正しました。

① Healer:test.fixme() でスキップしない

生成された Healer には、こう書かれていました。

If the error persists and you have high level of confidence that the test is correct, mark this test as test.fixme() so that it is skipped during the execution.

テストが正しいのに失敗し続けるなら、それはアプリの不具合です。スキップするとバグが隠れてしまいます。
Healer はファイルを直接書き換えられるので、ここは特に危ないです。

そこで、テストは変えずに失敗内容を報告させるようにしました。

.claude/agents/playwright-test-healer.md
-- If the error persists and you have high level of confidence that the test is correct, mark this test as test.fixme()
-  so that it is skipped during the execution. Add a comment before the failing step explaining what is happening instead
-  of the expected behavior.
+- If the error persists and you have high level of confidence that the test is correct (the failure is caused by a bug
+  in the application), do not modify the test. Never mark it as test.fixme(), test.skip(), or change its assertions to
+  match the buggy behavior. Instead, report the failing test, the failing step, the expected behavior, the actual
+  behavior, and the evidence (error message, page snapshot) so that the application can be fixed.

② Generator:生成例の構文ミス

生成例のコードが不正な構文になっていました。お手本が間違っていると、生成されるテストも間違えるので直します。

.claude/agents/playwright-test-generator.md
-    test('Add Valid Todo', async { page } => {
+    test('Add Valid Todo', async ({ page }) => {

③ Planner / Generator:seed ファイルを明示する

planner_setup_page / generator_setup_page に e2e/seed.spec.ts を渡すよう、定義に書き足しました。

ルールも整備する

.claude/rules/testing.md を、Unit と E2E で分けました。paths を指定しておくと、該当ファイルを触るときだけ読み込まれます。

  • testing-unit.md(paths: src/**/*.spec.{ts,tsx})
  • testing-e2e.md(paths: e2e/**, specs/**)

testing-e2e.md には、seed の前提やテストユーザーの作り方を書いています。

.claude/rules/testing-e2e.md
## Playwright Agents

- seed は `e2e/seed.spec.ts`(新規登録してログイン済みの状態にする)
- seed のログイン状態は後続のテストに引き継がれない。ログインが必要なテストは、各テストの冒頭で `createTestUser()` + `signup()` を行う
- テスト計画は `specs/`、生成したテストは `e2e/` に置く

なぜ Claude Code にしたか

init-agents は --loop で使うツールを選べます。VS Code(GitHub Copilot)向けの --loop=vscode もあり、こちらは .github/ 配下と .vscode/mcp.json が生成されます。

今回は、すでにハーネスを .claude/ に整備していて、Copilot は有料プランが必要になりやすいので、Claude Code(--loop=claude)にしました。

まとめ

  • npx playwright init-agents --loop=claude だけで、3つのエージェントと MCP サーバーの設定が入る
  • seed に「ログイン済みにする」準備を書いておくと、Planner / Generator がそこから作業を始められる
  • 生成されたエージェント定義はそのまま使わない。特に Healer の test.fixme() はアプリのバグを隠すので外す

次の実践編では、実際に Planner → Generator → Healer を動かして、どこまで任せられたかをまとめます。

資料

使用したAI

最初自分で書いて、AIに添削をもらいました。

Claude Code
ChatGPT

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?