Playwrightでは、テストコードを自動生成する機能 が次々に追加されています。
AIを活用した Agents 機能 や VS Code拡張機能との連携 など、テスト作成の自動化がどんどん進化しています。
この記事では、Playwrightに搭載された3種類のテスト生成方法を実際に試し、それぞれの使い方と特徴をまとめました。
前提
この記事は、前回の「Playwright導入編」で作成したBlazor画面を利用して進めます。
(先にそちらをご覧いただくと理解しやすいです)
以下の環境で動作確認を行っています。
os | windows11 |
.NET | 8.0.304 |
UI | Blazor(WebAssembly standalone) |
IDE | VS Code(1.105.0) |
playwright | 1.56 |
Agentsによるコード生成
Agents は、Playwright 1.56 で追加された新機能です。AIがテストプランの作成からテストコード生成、実行・修正までを自動で行ってくれます。GitHub Copilot と連携させることで、より精度の高いテスト生成が可能です。
初期設定
以下のコマンドで初期化します。
npx playwright init-agents --loop=vscode
VS Code v1.105以上が必要になります。
プロジェクトルートに以下のフォルダを作成しておきます。
- specs:テストプラン(Markdown)を格納するフォルダ
- tests:生成されたテストコードを格納するフォルダ
実行後、Copilotには次の3つのエージェントが追加されます:
- Planner:テストプランを作成
- Generator:テストコードを生成
- Healer:失敗したテストを自動修正

また、seed.spec.ts というファイルが自動生成されます。これは対象ページの情報をCopilotに伝えるためのファイルです。4行目の画面遷移を追記します。
test.describe('Test group', () => {
test('seed', async ({ page }) => {
// generate code here.
await page.goto('https://localhost:7013/sample');
});
});
その他、.github フォルダにはCopilotへの指示書(Markdown)が、.vscode フォルダにはMCPサーバー設定が追加されます。
テストプラン
まずは seed.spec.ts を開いた状態で、Copilotから Planner を選び、次のプロンプトを入力します。プロンプトはテスト内容に合わせて変えてください。
generate a test plan and save as a file in specs folder.
check the default value of this page.
execute search and check the result
change the dropdown values (uncheck US and check France) and search again and check the result.
修正後、Plannerは対象ページを自動で解析し、テストプランをMarkdown形式で作成します。



seedファイルをもとにサイトにアクセスして内容をMCPサーバーを用いて解析しています。こうして最終的にテストプランファイルが作成されました。その内容の一部を以下に記載します。
### 2. Basic Search Functionality
**Purpose:** Verify the search functionality works with default settings
**Steps:**
1. Leave the default language as "en (US)"
2. Leave the default country as "日本"
3. Enter search text in the search box
4. Click the "Search" button
**Expected Results:**
- Search should be executed
- Results should be displayed according to the default settings
- Search results should reflect the entered search criteria
概ね必要な項目が含まれていたため、次にテスト生成を行います。
テスト生成(Generator)
テストプラン(Markdown)を開いた状態で、Copilotに以下のプロンプトを入力します。
generate tests from "### 1. Default State Verification" section.
試行錯誤を繰り返しながらも、実際に画面を操作しながらテストを作成してくれています。実際にブラウザーが起動して、各種アクションを自動実行していく様子も確認できます。

セクション1のテストが作成されました。
test.describe('Default State Verification', () => {
test('verify initial page state', async ({ page }) => {
// 1. Navigate to the search page
await page.goto('https://localhost:7013/sample');
// 2. Verify default language selection
const localeSelect = page.getByRole('combobox', { name: 'Select your locale' });
await expect(localeSelect).toHaveValue('en-US');
// 3. Verify search input field is empty
const searchInput = page.getByRole('searchbox', { name: 'Search' });
await expect(searchInput).toHaveValue('');
// 4. Verify country selection and search message
const countrySelect = page.getByRole('combobox', { name: '国' });
await expect(countrySelect).toHaveValue('Japan');
await expect(page.getByText('検索してください')).toBeVisible();
});
});
残りのテストもすべて作成する中で、Copilotが自動的に改善提案も行ってくれました。
For the Search Results Display section (section 4), I notice it's more of a comprehensive test that involves multiple variations. I'll create a test suite that covers the different display scenarios
最終的にはテストプランが4セクションに分かれていたため、それぞれ別ファイルとして生成されました。

生成されたテストの一例です。
test.describe('Search Results Display', () => {
test('verify different result states', async ({ page }) => {
// 1. Navigate to the search page
await page.goto('https://localhost:7013/sample');
// 2. Verify initial state message
await expect(page.getByText('検索してください')).toBeVisible();
// 3. Search with default settings (Japan)
const searchButton = page.getByRole('button', { name: '検索' });
await searchButton.click();
// 4. Verify results format
await expect(page.getByText('名前')).toBeVisible();
await expect(page.getByText('国')).toBeVisible();
await expect(page.getByText('Takina')).toBeVisible();
await expect(page.getByText('Suzune')).toBeVisible();
// 5. Change country to France to verify empty results
await page.getByRole('button', { name: '国を選択' }).click();
await page.getByRole('checkbox', { name: 'フランス' }).click();
await page.getByRole('button', { name: '設定' }).click();
await page.getByLabel('国').selectOption('France');
await searchButton.click();
// 6. Verify empty results message
await expect(page.getByText('該当のユーザーは存在しません')).toBeVisible();
});
});
テストが作成できましたので、実行して結果を確認します。すると1件エラーが発生してしまいました。「国」という文字で要素を検索しているが、対象が複数(4)件あるので一つに絞れずエラーになっているようです。

修正(Healer)
生成されたテストは当然エラーが発生することもあります。そんなときは Healer 機能の出番です。エラーが出たテストファイルを開いたまま、エージェントをHealerに変更して次のプロンプトを入力します。
fix the test.
Healerはエラー原因を特定し、テストを自動的に修正してくれます。

修正後、再実行するとすべてのテストが正常に完了しました。

注意点
- セクションごとにテストファイルが分かれるため、1つにまとめたい場合は明示的に指示するか、後で手動で統合します。
- 過不足が発生するので内容はしっかり確認します。
- Copilot Freeプランではトークンを20〜30%ほど消費しました。Freeプラン利用者は注意が必要です。
VS Codeの拡張機能を使った生成
こちらは画面操作を記録してテストコードを生成する従来型の方法です。
Record New をクリックすると、test-1.spec.ts が生成され、記録用ブラウザが起動します。
画面操作を行うと対応するコードが自動で追記されます。

前回の記事と同じ内容をこの機能で実施して、最終的にできたテストコードが以下になります。一部アサーションメソッドが異なるものが使われていますが、概ね同じ結果となりました。
test('test', async ({ page }) => {
await page.goto('https://localhost:7013/sample');
await expect(page.getByRole('heading')).toContainText('ユーザー情報');
await expect(page.getByLabel('国')).toHaveValue('Japan');
await expect(page.getByText('検索してください')).toBeVisible();
await page.getByRole('button', { name: '検索' }).click();
await expect(page.getByText('Takina')).toBeVisible();
await page.getByRole('button', { name: '国を選択' }).click();
await page.getByRole('checkbox', { name: 'アメリカ' }).uncheck();
await page.getByRole('checkbox', { name: 'フランス' }).check();
await page.getByRole('button', { name: '設定' }).click();
await page.getByLabel('国').selectOption('France');
await page.getByRole('button', { name: '検索' }).click();
await expect(page.getByText('該当のユーザーは存在しません')).toBeVisible();
});
ちなみに、別ファイルを開いたまま操作すると、そちらにコードが追加されてしまう点に注意しましょう。
Codegen
Codegen は、CLIから起動するレコーディング機能です。基本的な動作はVS Code拡張と同じですが、VS Codeが不要で、生成コードが別ウィンドウに表示される点が異なります。
最後にコードをコピーして貼り付ける形になります。

まとめ
Playwrightでは、目的や環境に応じて複数のテスト生成方法を選択できます。
AIと連携したPlaywright Agentsは、テスト自動化の新しい可能性を感じさせます。
ただしまだ安定性には課題もあるため、用途に応じて従来のレコーディング機能と使い分けるのがおすすめです。
コメント