開発効率化

Claude Code × Playwright MCPで対話型UI自動テストを構築する

Claude CodeとPlaywright MCPを組み合わせて、ブラウザ操作を確認しながらUIテストを自動構築する方法をハンズオン形式で解説します。セットアップから実践的なテスト生成まで網羅。

2026年2月7日
Claude CodePlaywrightMCPテスト自動化UI テスト
Claude Code × Playwright MCPで対話型UI自動テストを構築する

はじめに

「テストを書く時間がない」——これは多くのフロントエンド開発者が抱える悩みです。

UIテストは重要だと分かっていても、セレクタの指定やテストシナリオの作成に時間がかかり、後回しにされがちです。さらに、UIの変更でテストが壊れるメンテナンスコストも無視できません。

もし、ブラウザを操作しながらAIに「今の操作をテストにして」と伝えるだけで、テストコードが自動生成されるとしたらどうでしょうか?

Claude CodeとPlaywright MCPを組み合わせれば、それが実現できます。本記事では、セットアップから実践的なテスト生成まで、ハンズオン形式で解説します。

Playwright MCPとは

Playwright MCPは、Microsoftが公式に提供するModel Context Protocol(MCP)サーバーです。Claude Codeなどの AI エージェントに、ブラウザ操作の能力を与えます。

従来のスクリーンショット方式との違い

Playwright MCPの最大の特徴は、アクセシビリティツリーを活用する点です。

項目スクリーンショット方式Playwright MCP
データサイズ数百KB〜数MB2〜5KB
解析速度Vision モデルが必要で低速構造化データで高速
精度ピクセル座標ベースで不安定アクセシビリティツリーで高精度
コスト画像トークンが高いテキストトークンのみ
セレクタ生成推測ベースロール・ラベルベースで堅牢

アクセシビリティツリーを使うことで、getByRole('button', { name: '送信' }) のような壊れにくいセレクタを自動生成できます。

セットアップ

前提条件

  • Node.js 18以上
  • Claude Code がインストール済み

Step 1: Playwright MCPをClaude Codeに登録

ターミナルで以下のコマンドを実行します。

claude mcp add playwright npx @playwright/mcp@latest

これだけで設定完了です。プロジェクトディレクトリごとに設定が保存されるため、他のプロジェクトには影響しません。

Step 2: 設定の確認

登録した設定は .mcp.json で確認できます。

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": [
        "@playwright/mcp@latest"
      ]
    }
  }
}

オプション設定

用途に応じてオプションを追加できます。

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": [
        "@playwright/mcp@latest",
        "--browser", "chrome",
        "--viewport-size", "1280x720"
      ]
    }
  }
}

主要なオプション一覧です。

オプション説明
--browserブラウザ種類chrome, firefox, webkit
--headlessヘッドレスモードCI環境向け
--viewport-size画面サイズ1280x720
--caps追加機能vision,pdf,devtools
--storage-state認証情報の読み込みauth.json

実践:対話型UIテストの構築

基本的な使い方

Claude Codeを起動し、Playwright MCPを使うよう指示します。

> Playwright MCPでhttp://localhost:3000を開いて、トップページの表示を確認して

ポイントは、最初のリクエストで**「Playwright MCP」**と明示的に伝えることです。これにより、Claude CodeがBashでの代替手段を試みることなく、MCP経由でブラウザを制御します。

実行すると、実際のChromeブラウザが起動し、Claude Codeがページの構造を解析します。

ユースケース1:フォームバリデーションのテスト生成

実際のプロジェクトで、お問い合わせフォームのテストを生成してみましょう。

> Playwright MCPで/contactページを開いて、
> フォームに何も入力せず送信ボタンを押して、
> バリデーションエラーが表示されることを確認して。
> その操作をPlaywrightのテストコードとして出力して。

Claude Codeは以下のような流れで動作します。

生成されるテストコードの例です。

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

test('お問い合わせフォーム - 未入力で送信するとバリデーションエラーが表示される', async ({ page }) => {
  await page.goto('/contact');

  // 送信ボタンをクリック
  await page.getByRole('button', { name: '送信' }).click();

  // バリデーションエラーの確認
  await expect(page.getByText('お名前は必須です')).toBeVisible();
  await expect(page.getByText('メールアドレスは必須です')).toBeVisible();
  await expect(page.getByText('お問い合わせ内容は必須です')).toBeVisible();
});

注目すべきは、getByRolegetByText といったアクセシビリティベースのセレクタが使われている点です。CSSクラス名やdata属性に依存しないため、UIリファクタリングでもテストが壊れにくくなります。

ユースケース2:ナビゲーションフローのテスト

ページ遷移を伴うテストも対話的に構築できます。

> トップページからブログ一覧に遷移して、
> 最初の記事をクリックして、記事タイトルが表示されることを確認して。
> 一連の操作をテストコードにして。
import { test, expect } from '@playwright/test';

test('トップページ → ブログ一覧 → 記事詳細の遷移', async ({ page }) => {
  await page.goto('/');

  // ブログ一覧へ遷移
  await page.getByRole('link', { name: 'ブログ' }).click();
  await expect(page).toHaveURL('/blog');

  // 最初の記事をクリック
  const firstArticle = page.getByRole('article').first();
  const articleTitle = await firstArticle.getByRole('heading').textContent();
  await firstArticle.getByRole('link').click();

  // 記事タイトルが表示されていることを確認
  await expect(page.getByRole('heading', { level: 1 })).toHaveText(articleTitle!);
});

ユースケース3:認証が必要なページのテスト

Playwright MCPの優れた点として、認証が簡単なことが挙げられます。ブラウザが可視化された状態で操作できるため、ログイン画面で自分の認証情報を手動入力できます。

> Playwright MCPでログインページを開いて

ブラウザが開いたら、手動でログインします。セッションCookieはセッション中ずっと保持されるため、その後は認証済みの状態でテストを進められます。

> ログインしたので、ダッシュボードのテストを作成して。
> ユーザー名が表示されていること、
> サイドバーのメニューが正しく動作することを確認して。

認証状態を保存して再利用することも可能です。

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": [
        "@playwright/mcp@latest",
        "--storage-state", "tests/auth.json"
      ]
    }
  }
}

CI/CDへの統合

対話的に作成したテストは、そのままCI/CDパイプラインで実行できます。

Playwrightのプロジェクト設定

// playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
  testDir: './tests/e2e',
  use: {
    baseURL: 'http://localhost:3000',
  },
  webServer: {
    command: 'npm run dev',
    port: 3000,
    reuseExistingServer: !process.env.CI,
  },
});

GitHub Actionsでの実行

# .github/workflows/e2e-test.yml
name: E2E Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npx playwright test
      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: playwright-report
          path: playwright-report/

テスト生成のワークフロー

実際の開発フローに組み込む場合の全体像を整理します。

効率的なテスト生成のコツ

コツ説明
ハッピーパスから始めるまず正常系を作成し、その後エラーケースを追加
ページオブジェクトを活用「このページのPage Objectも作って」と伝える
既存テストを参考にさせる「tests/e2eの既存テストに合わせて」と指示
認証状態は保存する--storage-state で認証済み状態を再利用
ヘッドレスで高速化CI環境では --headless を有効に

まとめ

Claude Code × Playwright MCPの組み合わせは、UIテスト構築の体験を大きく変えます。

  • アクセシビリティツリー活用により、スクリーンショット方式より高速・低コスト・高精度
  • 対話的なテスト生成で、ブラウザを操作しながら自然言語でテストを記述
  • 壊れにくいセレクタgetByRole, getByText)を自動生成
  • 認証も簡単——可視化ブラウザで手動ログイン後、そのままテスト作成
  • CI/CDにそのまま統合できる本番品質のテストコード

セットアップはコマンド1つ。まずは claude mcp add playwright npx @playwright/mcp@latest を実行して、自分のプロジェクトで試してみてください。「テストを書く時間がない」という悩みが、「テストは会話するだけ」に変わるはずです。


参考リンク: