Playwright テスト ガイド: Next.js アプリケーションの E2E テスト
エンドツーエンド テストは、認証フローの破損、フォーム送信の失敗、ナビゲーション エラー、クロスブラウザー レンダリングの問題など、単体テストで見逃されるバグをキャッチします。 Microsoft によって構築された Playwright は、マルチブラウザーのサポート、自動待機機能、および強力なデバッグ ツールを備えた主要な E2E テスト フレームワークになりました。
重要なポイント
- Playwright テストは、単一のテスト スイートから Chromium、Firefox、WebKit にわたって実行されます
- 自動待機により、要素が操作可能になるのを待ってから対話するため、不安定なテストが排除されます。
- 認証状態をテスト全体で共有して、実行を高速化できます。
- GitHub Actions との CI 統合により、すべてのプル リクエストの自動テストが可能になります
プロジェクトのセットアップ
インストール
npm init playwright@latest
これにより、Playwright がインストールされ、構成ファイルが作成され、ブラウザーのバイナリがダウンロードされます。 For Next.js projects, configure the web server to start automatically:
// playwright.config.ts
import { defineConfig } from "@playwright/test";
export default defineConfig({
testDir: "./e2e",
timeout: 30000,
retries: process.env.CI ? 2 : 0,
use: {
baseURL: "http://localhost:3000",
screenshot: "only-on-failure",
trace: "on-first-retry",
},
webServer: {
command: "npm run dev",
port: 3000,
reuseExistingServer: !process.env.CI,
},
projects: [
{ name: "chromium", use: { browserName: "chromium" } },
{ name: "firefox", use: { browserName: "firefox" } },
{ name: "webkit", use: { browserName: "webkit" } },
],
});
最初のテストを作成する
基本的なナビゲーション テスト
// e2e/navigation.spec.ts
import { test, expect } from "@playwright/test";
test("home page loads and displays title", async ({ page }) => {
await page.goto("/");
await expect(page).toHaveTitle(/ECOSIRE/);
await expect(page.getByRole("heading", { level: 1 })).toBeVisible();
});
test("navigation to services page", async ({ page }) => {
await page.goto("/");
await page.getByRole("link", { name: "Services" }).click();
await expect(page).toHaveURL(/services/);
await expect(page.getByRole("heading", { name: /Services/ })).toBeVisible();
});
フォーム送信テスト
test("contact form submission", async ({ page }) => {
await page.goto("/contact");
await page.getByLabel("Name").fill("Test User");
await page.getByLabel("Email").fill("[email protected]");
await page.getByLabel("Message").fill("This is a test message");
await page.getByRole("button", { name: "Send" }).click();
await expect(page.getByText("Message sent")).toBeVisible();
});
ページオブジェクトパターン
保守性を高めるために、ページ インタラクションをページ オブジェクトにカプセル化します。
// e2e/pages/login.page.ts
import { Page, expect } from "@playwright/test";
export class LoginPage {
constructor(private page: Page) {}
async goto() {
await this.page.goto("/login");
}
async login(email: string, password: string) {
await this.page.getByLabel("Email").fill(email);
await this.page.getByLabel("Password").fill(password);
await this.page.getByRole("button", { name: "Sign In" }).click();
}
async expectLoggedIn() {
await expect(this.page).toHaveURL(/dashboard/);
}
async expectError(message: string) {
await expect(this.page.getByText(message)).toBeVisible();
}
}
テストでの使用:
test("successful login", async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.goto();
await loginPage.login("[email protected]", "password123");
await loginPage.expectLoggedIn();
});
認証テスト
共有認証状態
認証状態を保存することで、毎回のテストの前にログインを回避します。
// e2e/auth.setup.ts
import { test as setup } from "@playwright/test";
setup("authenticate", async ({ page }) => {
await page.goto("/login");
await page.getByLabel("Email").fill("[email protected]");
await page.getByLabel("Password").fill("admin-password");
await page.getByRole("button", { name: "Sign In" }).click();
await page.waitForURL("/dashboard");
// Save authentication state
await page.context().storageState({ path: ".auth/user.json" });
});
playwright.config.ts で設定します。
projects: [
{ name: "setup", testMatch: /auth\.setup\.ts/ },
{
name: "authenticated",
dependencies: ["setup"],
use: { storageState: ".auth/user.json" },
},
],
視覚的な回帰テスト
スクリーンショットを比較して、意図しない視覚的な変更を検出します。
test("home page visual regression", async ({ page }) => {
await page.goto("/");
await expect(page).toHaveScreenshot("home-page.png", {
maxDiffPixelRatio: 0.01,
});
});
初回実行時に、Playwright はベースラインのスクリーンショットを保存します。後続の実行はベースラインと比較され、差がしきい値を超える場合は失敗します。変更が意図的である場合は、--update-snapshots を使用してベースラインを更新します。
API モック
決定論的テストのために API 応答を模擬します。
test("displays products from API", async ({ page }) => {
await page.route("/api/products", async (route) => {
await route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify([
{ id: 1, name: "Product A", price: 29.99 },
{ id: 2, name: "Product B", price: 49.99 },
]),
});
});
await page.goto("/products");
await expect(page.getByText("Product A")).toBeVisible();
await expect(page.getByText("Product B")).toBeVisible();
});
CI/CD の統合
GitHub アクション
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/
失敗したテスト レポートは、スクリーンショット、トレース、ビデオ録画など、デバッグ用のアーティファクトとしてアップロードされます。
デバッグツール
- Playwright Inspector: ステップバイステップで実行するために
--debugフラグを使用してテストを実行します - トレース ビューア: トレースを開いて、すべてのアクション、ネットワーク リクエスト、DOM スナップショットを確認します。
- Codegen:
npx playwright codegenを実行してブラウザーの操作を記録し、テスト コードを生成します。 - VS Code 拡張機能: 要素をクリックして配置することで、VS Code から直接テストを実行およびデバッグします
ベストプラクティス
- ロールベースのセレクターを使用: CSS セレクターよりも getByRole、getByLabel、getByText を優先します。
- ハードコードされた待機を避ける: page.waitForTimeout() の代わりに自動待機を信頼します。
- テストを分離する: 各テストは独立している必要があり、他のテストに依存しないでください。
- 実装ではなくユーザー フローをテスト: コードがどのように機能するかではなく、ユーザーが行うことに焦点を当てます。
- テストを高速に行う: セットアップに API ショートカットを使用します (UI ではなく API 経由でテスト データを作成します)
- CI で実行: すべてのプル リクエストはマージ前に E2E テストに合格する必要があります
よくある質問
Q: Playwright と Cypress を比較するとどうですか?
Playwright は複数のブラウザ (Chromium、Firefox、WebKit) をネイティブにサポートしていますが、Cypress は主に Chromium をターゲットとしています。 Playwright は並列実行が高速で、複数のタブ/ウィンドウを処理します。 Cypress は学習曲線が若干容易で、タイムトラベル デバッグが強力です。
Q: 不安定なテストはどのように処理すればよいですか?
Playwright の自動待機により、ほとんどの不安定さが解消されます。残りの問題については、Web ファースト アサーション (ロケーターを期待) を使用し、タイミング依存の動作のテストを回避し、CI で再試行を構成します。トレース レポートは、断続的な障害の根本原因を特定するのに役立ちます。
Q: すべてのページをテストする必要がありますか?
重要なユーザー フロー (認証、コア ビジネス ワークフロー、フォーム送信、支払いフロー) に焦点を当てます。すべてのページに E2E テストが必要なわけではありません。コンポーネント レベルをカバーするには単体テストと統合テストを使用してください。
Q: E2E テストにはどれくらい時間がかかりますか?
個々のテストは 30 秒以内に完了する必要があります。中規模のアプリケーション (50 ~ 100 のテスト) の完全なスイートは、並列実行で 10 分以内に実行されます。
次は何ですか
Playwright を使用した E2E テストにより、ユーザーの観点からアプリケーションが正しく動作するという確信が得られます。重要なフローから始めて、アプリケーションの成長に応じて対象範囲を拡大してください。
テスト自動化のヘルプについては ECOSIRE にお問い合わせ、品質が保証された ERP 導入については Odoo 実装サービス をご覧ください。
ECOSIRE が発行 -- エンタープライズ ソフトウェア ソリューションによるビジネスの拡大を支援します。
執筆者
ECOSIRE TeamTechnical Writing
The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.
関連記事
会計自動化: 2026 年に手動簿記を廃止
2026 年には、銀行フィードの自動化、レシートのスキャン、請求書の照合、AP/AR の自動化、月末締めの高速化により簿記を自動化します。
ビジネス向け AI エージェント: 決定版ガイド (2026)
ビジネス向け AI エージェントの包括的なガイド: AI エージェントの仕組み、ユースケース、実装ロードマップ、コスト分析、ガバナンス、2026 年の将来のトレンド。
AI エージェント vs RPA: どちらの自動化テクノロジーがあなたのビジネスに適していますか?
LLM を利用した AI エージェントと従来の RPA ボットの詳細な比較 - 機能、コスト、ユースケース、適切なアプローチを選択するための意思決定マトリックス。