はじめに
前回の【モダンWeb開発 発展編①】では、Codexそのものが持つエージェント実行機能を AGENTS.md、確定済み設計書、テストケース、停止条件によって制御し、テスト、デバッグ、修正、再テスト、Regression Testまでを自律的に進める方法を確認しました。
ただし、ここまでの自動テストだけでは確認しにくいものがあります。
それが、実際のブラウザを使った画面操作です。
ユーザー
↓
ブラウザ
↓
React + TypeScript
↓
Go API
↓
PostgreSQL
たとえば、
- 商品一覧が画面へ表示される
- ログイン後に画面が切り替わる
- カートへ商品を追加できる
- 数量変更が画面へ反映される
- 注文確認画面から注文を確定できる
- エラー発生時に適切なメッセージが表示される
といった確認は、ブラウザ操作まで含めたE2E(End-to-End)テストが適しています。
そこで発展編②では、Playwrightを導入し、これまで人間がブラウザで確認していた操作を自動化する方法を扱います。
この記事で分かること
- Playwrightとは何か
- E2Eテストとは何か
- Unit Test / Integration Test / E2E Testの違い
- Playwrightを利用するメリット
- PlaywrightとSeleniumの違い
- React + TypeScript + Go + PostgreSQL構成でのPlaywrightの位置づけ
- Playwrightの導入方法
- 最初のE2Eテストの作成方法
- LocatorとAssertionの基本
- Auto-waitingの考え方
- Headless / Headed / UI Modeの違い
- HTML ReportとTrace Viewerの使い方
- 既存の
docs/test-cases.mdとE2Eテストを対応させる考え方 - CodexとPlaywrightを組み合わせる方法
今回の構成
今回も、第2回から使用している開発環境を利用します。
Windows 11
↓
VS Code
↓
Dev Containers
↓
Docker Desktop
↓
Docker Compose
├─ app
│ ├─ React + TypeScript + Vite
│ ├─ Go
│ ├─ Node.js
│ ├─ Codex CLI
│ └─ Playwright
│
└─ db
└─ PostgreSQL
Playwrightはアプリケーション本体へ組み込むものではなく、ブラウザからアプリケーションを操作するテストツールとして利用します。
Playwright
↓
Browser
↓
React + TypeScript
↓
Go API
↓
PostgreSQL
E2Eテストとは
E2EはEnd-to-Endの略です。
システムの一部分だけではなく、ユーザーが実際に利用する流れに近い形でシステム全体を確認します。
今回のショッピングサイトなら、たとえば次の流れです。
商品一覧を開く
↓
商品詳細を開く
↓
ログインする
↓
カートへ追加
↓
数量を変更
↓
注文内容を確認
↓
注文を確定
↓
注文履歴を確認
GoのUnit TestではService単体、Repository TestではPostgreSQLとの接続、Handler TestではHTTP Handlerなどを確認できます。
E2Eテストでは、その上にあるブラウザ操作まで含めて確認します。
テストの役割を整理する
今回のプロジェクトでは、テストを次のように考えることができます。
| テスト | 主な対象 | 確認する内容 |
|---|---|---|
| Unit Test | 関数・Serviceなど | 個々のロジック |
| Handler Test | HTTP Handler | Request / Response |
| Repository Test | Repository + PostgreSQL | SQL・DB制約・データ取得 |
| Integration Test | Handler → Service → Repository → DB | 複数レイヤーの連携 |
| Frontend Test | React Componentなど | UIロジック |
| E2E Test | Browser → Frontend → Backend → DB | 実際のユーザー操作に近い一連の処理 |
Playwrightは、最後のE2E Testを担当します。
Playwrightを使えばUnit TestやIntegration Testは不要になるのか
Playwrightを導入しても、既存のUnit TestやIntegration Testを置き換えるわけではありません。
今回のショッピングサイトでは、次のように役割を分けます。
| テスト | 今回使うもの | 主な確認範囲 |
|---|---|---|
| Unit Test | Go testing / Frontendの既存テスト |
Service、Validation、個別ロジックなど |
| Integration Test | Go testing + PostgreSQL |
Handler → Service → Repository → PostgreSQL |
| E2E Test | Playwright | Browser → React → Go API → PostgreSQL |
| Manual Test | 人間 | 見た目や操作感など、自動化しにくい確認 |
Playwrightはブラウザからシステム全体を操作できるため、結合されたシステムの動作も確認できます。ただし、今回すでに作成しているGoのIntegration TestをPlaywrightへ置き換えるのではなく、その外側からユーザー操作を確認するE2E Testとして追加します。
【Unit Test】
Service
Validation
個別関数
Reactの個別ロジック
↓
Go testing / Frontend Test
【Integration Test】
Handler
↓
Service
↓
Repository
↓
PostgreSQL
↓
Go testing
【E2E Test】
Playwright
↓
Browser
↓
React
↓
Go API
↓
PostgreSQL
E2E Testは画面からDBまでを一度に通すため、どこか1か所に問題があると結果に表れます。一方で、その問題がReact、Go API、Service、Repository、SQL、DB制約のどこにあるのかまでは、E2E Testだけでは絞り込めません。
Unit TestやIntegration Testがあれば、より狭い範囲で動作を確認できます。そのため、低いレイヤーのテストを残したうえで、主要なユーザーフローをPlaywrightで確認する構成にします。
PlaywrightにはReactなどを対象にしたComponent Testの仕組みもありますが、今回の連載では既存のFrontend Testを置き換えず、PlaywrightはE2E Testに利用します。
つまり今回の位置づけは、
第6回
├─ Go Unit Test
├─ Handler Test
├─ Repository Test
├─ Integration Test
└─ Frontend Test
+
発展編②
└─ Playwright E2E Test
├─ ログイン
├─ 商品検索
├─ カート追加
├─ 数量変更
├─ 注文確認
├─ 注文確定
└─ 注文履歴
です。
Playwrightは第6回のテストを置き換えるものではなく、第6回で残っていたブラウザ確認を自動化し、既存のテスト体系を補完するために利用します。
Playwrightとは
Playwrightは、Webブラウザをプログラムから操作してWebアプリケーションをテストできるツールです。
Playwright Testを利用すると、テストランナー、Assertion、並列実行、ブラウザ制御、レポート、Traceなどをまとめて利用できます。
対応する代表的なブラウザエンジンは次のとおりです。
Chromium
Firefox
WebKit
Chromium系ではGoogle ChromeやMicrosoft Edgeを利用する構成も可能です。
Playwrightを使うメリット
今回のようなReactアプリケーションでは、特に次の点が便利です。
ブラウザ操作をコード化できる
人間が毎回、
ブラウザを開く
↓
ログイン
↓
商品を選択
↓
カートへ追加
↓
注文
と操作する代わりに、テストコードとして残せます。
Auto-waiting
Web画面では、要素が表示される前にクリックしようとするとテストが不安定になります。
Playwrightは操作前に対象要素の状態を確認し、必要な条件が満たされるまで自動的に待機します。
そのため、固定時間の待機を大量に書くのではなく、画面の状態を基準にテストしやすくなります。
Headlessで実行できる
通常のテストでは、ブラウザ画面を表示せずに実行できます。
Terminal
↓
Playwright
↓
Headless Browser
↓
Test
CI/CDでも利用しやすい構成です。
実行内容を後から確認できる
HTML Reportで各テストの結果を一覧でき、Trace Viewerを利用すると、テスト実行時の操作、DOM、Network、Consoleなどを1ステップずつ確認できます。
E2E Test
↓
HTML Report
↓
Trace Viewer
↓
操作・DOM・Networkを確認
発展編①で扱ったCodexによるデバッグとも組み合わせやすい機能です。
Seleniumとの違い
ブラウザ自動化ではSeleniumも広く利用されています。
Selenium WebDriverはW3C WebDriverを利用して主要ブラウザを操作する仕組みで、複数言語から利用でき、Selenium Gridによる分散実行など長年使われてきたエコシステムがあります。
一方、PlaywrightはE2Eテストに必要な機能をまとめて利用しやすく、今回のTypeScript中心のFrontendプロジェクトへ導入しやすい特徴があります。
| 観点 | Playwright | Selenium |
|---|---|---|
| 主な用途 | WebアプリのE2E・ブラウザ自動化 | Webブラウザ自動化 |
| TypeScript / JavaScript | 利用可能 | 利用可能 |
| ブラウザ操作 | Playwright API | WebDriver API |
| Auto-waiting | 標準機能として利用しやすい | Waiting Strategyを利用 |
| Test Runner | Playwright Testを利用可能 | 利用言語・構成に応じて選択 |
| Trace | Trace Viewerを利用可能 | 構成に応じてログ等を利用 |
| 分散実行 | CI等で並列化可能 | Selenium Gridが代表的 |
| 今回のReact + TypeScript構成 | 導入しやすい | 導入可能 |
Seleniumが古いからPlaywrightを使う、という単純な比較ではありません。
Seleniumは複数言語や既存資産、WebDriverを利用した幅広いブラウザ自動化で強みがあります。
今回Playwrightを選ぶ理由は、React + TypeScriptの学習用ショッピングサイトでE2Eテストを追加し、Frontend側のTypeScriptと同じ言語でテストコードを書きやすいからです。
Playwrightを導入する
Dev Container内で作業します。
まずFrontendへ移動します。
cd /workspaces/shopping-site/frontend
Playwright Testを開発依存として追加します。
npm install -D @playwright/test
続いて、テストで利用するブラウザと、Linux Containerで必要なOS依存パッケージをまとめてインストールします。今回はChromiumだけを使うため、Chromiumに絞って導入します。
npx playwright install --with-deps chromium
--with-deps はOSパッケージを導入するため、root権限(またはsudo)が必要です。Dev Containerの利用ユーザーにsudo権限がない場合は、Dev Containerの設定でOSパッケージを導入しておきます。
インストール後はpackage.jsonとpackage-lock.jsonの変更内容を確認します。
あわせて、package.jsonのscriptsへE2Eテスト用のコマンドを追加しておくと、以降の操作が短くなります。
{
"scripts": {
"test:e2e": "playwright test"
}
}
既存のscriptsは残したまま、test:e2eだけを追加します。
生成物をGit管理から外す
Playwrightは実行結果を次のフォルダへ出力します。
| フォルダ | 内容 |
|---|---|
test-results/ |
テストごとの出力(Traceなど) |
playwright-report/ |
HTML Report |
実行のたびに作り直される生成物なので、frontend/.gitignoreへ追加します。
/test-results/
/playwright-report/
Playwrightの設定ファイルを作成する
Frontend直下にplaywright.config.tsを作成します。
frontend
├─ src
├─ tests
│ └─ e2e
├─ package.json
├─ vite.config.ts
└─ playwright.config.ts
設定例です。
import { defineConfig, devices } from '@playwright/test'
export default defineConfig({
testDir: './tests/e2e',
retries: process.env.CI ? 2 : 0,
reporter: 'html',
use: {
baseURL: 'http://127.0.0.1:5173',
trace: 'on-first-retry',
},
webServer: {
command: 'npm run dev -- --host 127.0.0.1 --port 5173 --strictPort',
url: 'http://127.0.0.1:5173',
reuseExistingServer: !process.env.CI,
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
],
})
各設定の意味は次のとおりです。
| 設定 | 意味 |
|---|---|
testDir |
E2Eテストを置くフォルダ |
retries |
失敗したテストを再試行する回数。CIでは2回、ローカルでは0回 |
reporter |
htmlを指定すると、実行結果をHTML Reportとして出力する |
baseURL |
page.goto('/')のような相対パスの基準URL |
trace |
Traceを記録する条件。on-first-retryは最初の再試行時に記録する |
webServer |
テスト開始前にViteの開発サーバーを起動し、URLが応答するまで待つ |
projects |
テストに使うブラウザ。今回はChromiumだけ |
webServerのreuseExistingServerをtrueにすると、すでにnpm run devでViteを起動している場合はそのサーバーを使い、起動していなければPlaywrightが起動します。どちらの状態からでも同じコマンドでテストを始められます。
Viteの起動時に--host 127.0.0.1を指定しているのは、baseURLと待ち受けアドレスを一致させるためです。
最初はChromiumだけに限定して、E2Eテストの作成と実行方法を理解します。
必要になった段階でFirefoxやWebKitを追加できます。
Go APIとPostgreSQLを起動しておく
webServerで自動起動するのはFrontend(Vite)だけです。
E2Eテストは画面からGo API、PostgreSQLまでを通すため、テストを実行する前に、第6回までと同じ手順でdbコンテナとGo APIを起動しておきます。
db(PostgreSQL) … 起動済み
Go API … 起動済み
Frontend(Vite) … Playwrightが起動
最初のE2Eテストを作成する
まず、商品一覧画面を開けることを確認します。
frontend/tests/e2e/products.spec.tsを作成します。
import { test, expect } from '@playwright/test'
test('商品一覧画面を表示できる', async ({ page }) => {
await page.goto('/')
await expect(page).toHaveTitle(/.+/)
})
この段階では、アプリケーション固有の文言やDOM構造を推測してテストへ書かず、「ページを開けて、タイトルが空でない」ことだけを確認します。
実際の画面実装とdocs/test-cases.mdを確認し、確定している内容をAssertionへ反映していきます。
テストを実行する
E2Eテストを実行します。
npm run test:e2e
npx playwright testでも同じです。
Playwright Testは通常Headlessで実行されます。実行が終わると、ターミナルに結果が表示されます。
Running 1 test using 1 worker
1 passed
ブラウザを表示しながら確認する場合は、
npx playwright test --headed
を利用します。
Dev Container内でブラウザ画面を表示するには、コンテナ側にGUIを表示できる環境が必要です。表示環境がない場合は、次のUI ModeやHTML Reportを利用すると、Headlessのまま画面の様子を確認できます。
LocatorとAssertionで画面を操作する
最初のテストが動いたら、画面の要素を操作・確認するテストへ広げます。
Locator
PlaywrightではLocatorを使って画面上の要素を指定します。
たとえば、ボタンをRoleで取得する場合は次のように書けます。
const button = page.getByRole('button', { name: 'カートに追加' })
await button.click()
入力欄なら、
await page.getByLabel('メールアドレス').fill('user@example.com')
のように操作できます。
CSS Selectorだけに依存するより、ユーザーが認識するRoleやLabelを利用できる場合は、それらを優先するとテストの意図が分かりやすくなります。
Assertion
画面操作だけではテストになりません。
操作後に期待する状態を確認します。
await expect(page.getByRole('heading', { name: 'カート' })).toBeVisible()
Playwrightの操作とAssertionは、Locatorが1つの要素だけに一致することを前提にしています(strict mode)。
page.getByText('カート')のように画面上の文字だけで指定すると、ヘッダーの「カート」リンクと見出しの「カート」の両方に一致してしまうことがあります。上の例のように、getByRoleでRoleと名前を組み合わせて、確認したい要素を1つに絞ります。
たとえばログインなら、
メールアドレス入力
↓
パスワード入力
↓
ログイン
↓
期待する画面状態を確認
という形になります。
文言・Role・Labelは推測で書かず、実際の画面実装とdocs/test-cases.mdで確定しているものを使います。
Auto-waitingを利用する
E2Eテストでありがちな実装は、固定時間の待機です。
await page.waitForTimeout(3000)
しかし、毎回3秒待てば安全というわけではありません。
PlaywrightではLocatorの操作やAssertionで必要な状態を待機できるため、固定時間の待機を書く必要はありません。
await expect(page.getByRole('heading', { name: '注文履歴' })).toBeVisible()
このAssertionは、見出しが表示されるまで自動的に待ってから確認します。
テスト対象の状態を待つことで、実行環境の速度差に左右されない安定したテストになります。
UI Modeで確認する
テストを作成するときはUI Modeが便利です。
npx playwright test --ui
テストを選択して実行し、各ステップの画面やDOMを確認しながら作業できます。
通常のRegression TestはHeadless、テストの作成や動作確認ではUI Modeという使い分けができます。
HTML ReportとTrace Viewerで実行内容を確認する
E2Eテストでは、テストがどのように動いたかを後から確認できることが重要です。
HTML Report
設定でreporter: 'html'を指定しているため、テストを実行するとplaywright-report/へHTML Reportが出力されます。
npx playwright show-report
ブラウザでレポートが開き、テストごとの結果や実行時間を確認できます。
Traceを記録して確認する
今回の設定のtrace: 'on-first-retry'は、最初の再試行時にTraceを記録する設定です。
再試行はCIでだけ行う設定(retries: process.env.CI ? 2 : 0)にしているため、この設定はCIで不安定なテストの記録を残すためのものです。
ローカルでTraceを確認したいときは、実行時に--trace onを指定します。
npx playwright test --trace on
--trace onは設定ファイルのtraceを上書きし、実行したすべてのテストでTraceを記録します。
記録したTraceは、HTML Reportから開けます。
npx playwright show-report
レポートで対象のテストを選ぶと、Traceの項目が表示されます。
Trace Viewerでは、
各操作(goto / click / fill / expect)
↓
その時点の画面とDOM
↓
Network / Console
を1ステップずつ確認できます。
Traceはtest-results/配下の各テストのフォルダへtrace.zipとして保存されるため、ファイルを直接指定して開くこともできます。
npx playwright show-trace test-results/<テストごとのフォルダ>/trace.zip
| 実行場所 | Traceの記録方法 |
|---|---|
| CI |
retriesとtrace: 'on-first-retry'で、再試行時に記録 |
| ローカル |
--trace onで、確認したいときに記録 |
docs/test-cases.mdと対応させる
今回重要なのは、Playwrightを導入したからといって新しいテスト仕様を勝手に作らないことです。
第6回で使用したdocs/test-cases.mdを基準にします。
docs/test-cases.md
↓
117 TC
↓
自動テストで確認済み
+
ブラウザ確認が必要
↓
Playwrightへ移行可能か確認
まずManualまたはA+Mとして残っているテストケースを確認します。
そのうえで、
TC-ID
↓
画面操作
↓
期待結果
↓
Playwright Test
と対応させます。
テスト名にTC-IDを含めておくと、HTML Reportからも対応が追えます。
test('TC-XXX 商品一覧画面を表示できる', async ({ page }) => {
// ...
})
TC-XXXの部分には、docs/test-cases.mdの実際のIDを使います。
すべてのManual Testを無理に自動化しない
Playwrightを導入しても、Manual Testをゼロにすること自体を目的にしません。
判断基準は、
自動化することで
繰り返し確認する価値があるか
です。
たとえば、
ログイン
カート追加
数量変更
注文確認
注文確定
注文履歴
のような主要フローはRegression Testとして繰り返し実行する価値があります。
一方、一度だけ確認すれば十分な見た目の細部まで無理に自動化すると、テスト保守コストが増える場合があります。
E2Eテスト用データをどうするか
ここは第6回のIntegration Testと大きく違うポイントです。
BackendのIntegration Testでは、step6_test_<UUID> Schemaやpg_tempを利用してテストデータを隔離しました。
E2Eテストでも、通常の開発データを無計画に書き換える構成は避けます。
Playwright
↓
Browser
↓
Frontend
↓
Backend
↓
Test Data
E2E用データについては、既存の確定仕様、既存Fixture、BackendのSetup方法を確認し、再現可能な初期状態を作る方法を決めます。
ここで新しいDB、Schema、専用APIなどが必要になる場合は、既存仕様から一意に判断できる軽微な変更ではありません。
発展編①と同じく、設計判断が必要ならCodexに勝手に決めさせず、人間へ戻します。
CodexにPlaywrightテストを作成させる
今回もCodexを利用できます。
Dev Container内でプロジェクトルートへ移動します。
cd /workspaces/shopping-site
codex
Codexには、まず既存仕様と画面実装を確認させます。
docs/test-cases.mdと既存Frontend実装を確認し、ブラウザ操作が必要なManualまたはA+Mのテストケースを整理してください。
まだファイルは変更しないでください。
各TCについて、
- TC-ID
- 対象画面
- 操作
- 期待結果
- Playwrightで自動化可能か
- 自動化する場合に必要なテストデータ
- 現在の既存FixtureやSetupを再利用できるか
を整理してください。
docs/test-cases.mdに存在しない仕様を推測しないでください。
最初から「全部Playwright化してください」と指示するのではなく、まず自動化対象とデータ準備方法を確認します。
Playwright実装をCodexへ指示する
対象を確認したあと、実装を依頼します。
前回整理したPlaywright自動化対象について、docs/test-cases.mdの確定仕様を基準としてE2Eテストを実装してください。
重要:
- docs/test-cases.mdの期待結果を独断で変更しない
- 本番コードをテスト都合で変更しない
- 新しいAPIを勝手に追加しない
- DB Schemaを変更しない
- 認証・認可方式を変更しない
- 既存の画面実装とアクセシビリティ情報を確認してLocatorを選ぶ
- Locatorは1つの要素に一致するように指定する
- 固定時間のwaitを使用しない
- 既存Fixture・Setupを優先して再利用する
- テスト名にTC-IDを含め、TC-IDとPlaywright Testの対応を追跡できるようにする
実装後は、
1. Playwright Testを実行(調査が必要な場合は --trace on を付けて実行)
2. FAILした場合はTraceとHTML Reportで原因を調査
3. 確定仕様から一意に判断できる軽微な不整合だけを修正
4. 該当テストを再実行
5. 関連E2E Testを実行
6. Regression Testを実行
7. 結果をdocs/test-results.mdへ記録
まで行ってください。
設計変更が必要な場合は停止し、
- TC-ID
- 関連設計書
- 現在の実装
- 発見した差異
- 判断が必要な理由
を報告してください。
発展編①で作ったエージェントハーネスの考え方を、そのままPlaywrightへ適用できます。
Codex + Playwrightでテスト工程をつなげる
最終的には次のような流れになります。
docs/test-cases.md
↓
Codex
↓
Playwright Test作成
↓
Browser
↓
React
↓
Go API
↓
PostgreSQL
↓
PASS?
/ \
Yes No
| |
| Trace確認
| ↓
| 原因分析
| ↓
| 軽微な不整合?
| / \
| Yes No
| | |
| Fix 人間へ報告
| |
| Retest
| |
└───────┘
↓
Regression Test
↓
docs/test-results.md
これで、発展編①の「テスト・デバッグ・再テストの自律化」をブラウザテストまで広げられます。
PlaywrightとCodexの役割
両者の役割を混同しないことも重要です。
Codex
├─ docsを読む
├─ テストコードを作る
├─ テストを実行する
├─ FAILを分析する
├─ 許可範囲なら修正する
└─ 結果を記録する
Playwright
├─ Browserを起動する
├─ 画面を操作する
├─ UI状態を確認する
├─ Networkを含む実行情報を取得する
└─ E2E Testを実行する
Playwright自体が仕様を判断するわけではありません。
Codexが確定仕様とガードレールを基準にテスト工程を進め、Playwrightがブラウザ操作を実行する構成です。
Regression Testへ組み込む
Playwrightテストが安定したら、Backend / Frontendのテストと合わせてRegression Testへ組み込めます。
Go Unit Test
↓
Go Integration Test
↓
Frontend Test
↓
Playwright E2E Test
↓
Build
将来的にはCI/CDで、
Git Push
↓
CI
├─ Go Test
├─ Frontend Test
├─ Playwright
└─ Build
という構成へ発展させることもできます。
CIでは環境変数CIが設定されるため、今回の設定のまま、
- 失敗したテストを最大2回再試行する
- 最初の再試行時にTraceを記録する
- 既存サーバーを再利用せず、Viteを新しく起動する
という動作に切り替わります。
ただし、最初からCI/CDまで広げるのではなく、今回はローカルのDev ContainerでE2Eテストを安定して実行できる状態を目標にします。
Seleniumとどちらを使うべきか
今回のプロジェクトではPlaywrightを利用しますが、Seleniumが不要という意味ではありません。
考え方としては次のように整理できます。
React + TypeScript
新規E2Eテスト
Playwright Testをまとめて利用したい
↓
Playwrightが導入しやすい
既存Selenium資産がある
複数言語から利用する
WebDriver / Gridを中心に運用している
↓
Seleniumを継続する選択肢がある
ツール名だけで優劣を決めるのではなく、既存資産、チームの技術、対象ブラウザ、CI環境、テスト規模などで選択します。
発展編①との関係
発展編①では、
Codex
↓
Test
↓
Debug
↓
Fix
↓
Retest
↓
Regression Test
という自律テスト工程を作りました。
発展編②では、そこへPlaywrightを追加します。
Codex Agent Harness
↓
┌─────┴─────┐
↓ ↓
Go Test Playwright
↓ ↓
API / DB Browser
└─────┬─────┘
↓
Regression Test
↓
docs/test-results.md
これにより、Backend / API / DBだけでなく、実際のブラウザ操作まで自動テストの対象へ広げられます。
まとめ
今回は、Playwrightを利用してReact + TypeScript + Go + PostgreSQLで作成したショッピングサイトのブラウザテストを自動化する考え方を確認しました。
Playwrightを導入することで、
人間がブラウザを操作
↓
目視確認
としていた工程の一部を、
Playwright
↓
Browser
↓
React
↓
Go API
↓
PostgreSQL
↓
Assertion
として繰り返し実行できるテストへ変えられます。
導入時のポイントは次のとおりです。
| ポイント | 設定・書き方 |
|---|---|
| Frontendの起動 |
webServerでViteを自動起動し、URLの応答を待つ |
| 実行結果の確認 |
reporter: 'html'とnpx playwright show-report
|
| Traceの記録 | CIはon-first-retry+retries、ローカルは--trace on
|
| 要素の指定 |
getByRole / getByLabelで1つの要素に絞る |
| 待機 | 固定時間ではなく、Assertionで画面の状態を待つ |
また、発展編①のCodexによるエージェント実行と組み合わせることで、
テスト作成
↓
実行
↓
FAIL
↓
原因分析
↓
修正
↓
再テスト
↓
Regression Test
までを一連のテスト工程として扱えます。
重要なのは、Playwrightを導入したからといって、既存のUnit TestやIntegration Testを置き換えないことです。
Unit Test
Integration Test
Frontend Test
E2E Test
にはそれぞれ役割があります。
今回のPlaywrightは、第6回で残っていたブラウザ操作の確認を自動化し、既存のテスト体系を補完する位置づけです。
発展編①で「Codexにどこまで自律的にテスト工程を任せるか」を整理し、発展編②では「ブラウザ操作をどこまで自動化するか」を整理しました。
これにより、ショッピングサイトのテスト工程を、Backend、Frontend、Database、Browserまで段階的に広げることができます。
本連載について
| 回 | タイトル | 対応範囲 | 主な内容 |
|---|---|---|---|
| 第1回 | Docker × VS Code Dev ContainersでGo開発環境を構築する | 🐳 Go開発環境 | Docker Desktop・VS Code・Dev Containersを使ったGo開発環境の構築 |
| 第2回 | React + TypeScript + Go + PostgreSQLのフルスタック開発環境を構築する | 🛠️ フルスタック開発環境 | Docker Desktop・Dev Containers・React・TypeScript・Go・PostgreSQL・Node.js・Vite |
| 第3回 | ChatGPT Workでショッピングサイトを設計してみる | 📐 システム設計 | Project instructions・要件定義・ユースケース・画面設計・ER図・DB設計・REST API設計・テストケース仕様書 |
| 第4回 | Codex × AGENTS.md × Skillsで実装準備を整える | 🤖 AI開発ルール | AGENTS.md・プロジェクトルール・階層化・Skills・実装準備 |
| 第5回 | Codexで設計書からショッピングサイトを実装する | 🛒 ショッピングサイト実装 | 設計書・AGENTS.md・Skillsを活用した段階的なAI開発・実装・検証 |
| 第6回 | Codexで実装したショッピングサイトをテスト・動作確認する | 🧪 テスト・動作確認 | test-cases.md・ユニットテスト・結合テスト・API・ブラウザ・DBによる動作確認 |
| 発展編① | Codexのエージェントハーネスでテスト・デバッグ・再テストを自律化する | 🤖 エージェントハーネス | AGENTS.md・確定仕様・テストケース・停止条件を利用したテスト・デバッグ・修正・再テスト・Regression Testの自律化 |
| 発展編② | Playwrightでブラウザテストを自動化する | 🎭 E2Eテスト自動化 | Playwright・E2Eテスト・ブラウザ操作・Auto-waiting・HTML Report・Trace Viewer・Seleniumとの違い・Codexとの連携 |