目次

PlaywrightのE2Eテストコードを自然言語の仕様からAIに生成させることで、テスト作成の工数を大幅に削減できる。しかし動的なUI・認証フロー・非同期処理など、AIが苦手とする領域も存在する。AIが生成するテストの精度と限界を把握した上で、適切に活用する方法を解説する。

AIによるPlaywrightテスト生成の基本

効果的なプロンプトの書き方

AIにテストコードを生成させる際は、「何をテストするか」を具体的に伝えることが重要だ。

Playwrightで以下のシナリオをテストするTypeScriptコードを書いてください。

【テスト対象】
ログインフォーム(URL: http://localhost:3000/login)

【テストシナリオ】
1. メールアドレスとパスワードを入力してログインボタンをクリックする
2. ダッシュボードページ(/dashboard)にリダイレクトされることを確認する
3. ページ上にユーザー名が表示されていることを確認する

【補足情報】
- メールアドレス入力: id="email"
- パスワード入力: id="password"
- ログインボタン: テキスト "ログイン"
- ダッシュボードのユーザー名表示: data-testid="user-name"

セレクターの情報(id・テキスト・data-testid)を事前に伝えると、生成されるコードの精度が大幅に上がる。

生成コードの基本パターン

AIが生成するPlaywrightテストは概ね以下の構造になる。

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

test("ログインしてダッシュボードに遷移する", async ({ page }) => {
  // ページを開く
  await page.goto("http://localhost:3000/login");

  // フォームに入力
  await page.fill("#email", "test@example.com");
  await page.fill("#password", "password123");

  // ログインボタンをクリック
  await page.getByRole("button", { name: "ログイン" }).click();

  // リダイレクトの確認
  await expect(page).toHaveURL(/.*dashboard/);

  // ユーザー名の表示確認
  await expect(page.getByTestId("user-name")).toBeVisible();
});

AIが得意なこと・苦手なこと

得意なパターン

静的なUIの操作: ボタンクリック・フォーム入力・ページ遷移の基本操作は高精度で生成できる。

明確な期待値がある確認: URLの確認・テキストの存在確認・要素の表示/非表示は信頼性が高い。

ハッピーパスの記述: 正常系のフローは、仕様を正確に伝えれば再利用可能なコードが生成できる。

苦手なパターン

動的に変化するUI: サーバーサイドレンダリングの遅延・アニメーション・ポーリングなど、タイミングに依存する操作は適切な待機処理が必要だ。AIは標準的な waitForSelector を追加することがあるが、実際の待機条件に合わない場合がある。

認証・セッション管理: OAuthフロー・多要素認証・クッキーの状態管理は複雑で、AIが正確なテストを生成しにくい。

動的に生成されるセレクター: ランダムなid・時刻ベースのセレクターなど、予測できないセレクターの扱いはAIには難しい。

タイミング問題の対処法

AIが生成したテストが不安定(flaky)になる原因の多くはタイミング問題だ。

適切な待機処理の追加

// 悪い例: 固定時間の待機
await page.waitForTimeout(3000); // 不安定になりやすい

// 良い例: 要素の状態を待つ
await page.waitForSelector('[data-testid="result"]', { state: "visible" });

// 良い例: APIレスポンスを待つ
const responsePromise = page.waitForResponse("/api/login");
await page.click("#login-button");
await responsePromise;

AIに「固定時間の待機を使わず、要素の状態変化を待つ形式で書いてください」と明示することで、生成コードの品質が上がる。

ネットワーク状態との同期

// リクエストの完了を待ってから確認する
await page.waitForLoadState("networkidle");
await expect(page.getByTestId("data-list")).toBeVisible();

認証のベストプラクティス

テストごとにログインフローを実行すると、テスト時間が長くなりE2Eテスト全体が重くなる。Playwrightのストレージステートを使ってセッションを再利用する方法をAIに提案させると、効率的なテスト設計が得られる。

// グローバルセットアップでログイン状態を保存する
// (global-setup.ts)
import { chromium, FullConfig } from "@playwright/test";

async function globalSetup(config: FullConfig) {
  const browser = await chromium.launch();
  const page = await browser.newPage();

  await page.goto("http://localhost:3000/login");
  await page.fill("#email", process.env.TEST_EMAIL!);
  await page.fill("#password", process.env.TEST_PASSWORD!);
  await page.click('[type="submit"]');
  await page.waitForURL("**/dashboard");

  // ストレージステートを保存
  await page.context().storageState({ path: "playwright/.auth/user.json" });
  await browser.close();
}

export default globalSetup;

AIが生成したテストのレビューチェックリスト

AIが生成したテストコードを採用する前に、以下の点を確認する。

  • セレクターがアクセシビリティ属性(role・label)またはdata-testidを使っているか(クラス名やXPathは変更に弱い)
  • 固定時間の waitForTimeout が使われていないか
  • 機密情報(テスト用パスワード・APIキー)がハードコードされていないか
  • エラーパターン(失敗時のログイン・不正入力など)のテストが含まれているか

まとめ

AIはPlaywrightの基本的なE2Eテストコードを効率よく生成できる。セレクター情報を事前に伝え、「固定時間の待機を避け、要素状態の待機を使うこと」を指示することで生成品質が上がる。動的UI・認証フロー・タイミング依存の処理は人間がレビューして補完する必要がある。AIを「テストコードの下書き生成者」として使い、レビューチェックリストで品質を担保するワークフローが実践的なアプローチだ。

免責事項 — 掲載情報は執筆時点のものです。料金・機能は変更される場合があります。最新情報は各公式サイトをご確認ください。