フォームとユーザーフローのE2Eテスト
Playwrightのpage objectsで、複数ステップのフォーム送信とナビゲーションフローを自動化します。
「フォームとユーザーフローのE2Eテスト」はCoddyKit上の無料React Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。
E2Eフォームテスト戦略
E2Eフォームテストでは、ページを開き、フィールドに入力し、送信し、バリデーションエラーに対処して、成功結果を確認するというユーザーの一連の操作を再現します。
ページオブジェクトモデル
ページオブジェクトモデル(POM)は、ページのセレクターと操作をクラスにまとめることで、テストの可読性を高め、重複を減らします。
class LoginPage {
constructor(private page: Page) {}
async goto() { await this.page.goto('/login'); }
async fillEmail(email: string) { await this.page.getByLabel('Email').fill(email); }
async fillPassword(pw: string) { await this.page.getByLabel('Password').fill(pw); }
async submit() { await this.page.getByRole('button', { name: /log in/i }).click(); }
async getError() { return this.page.getByRole('alert').textContent(); }
}テストでのページオブジェクトの使用
ページオブジェクトを使用すると、テストはユーザーの操作を意図のレベルで表す記述になり、読みやすく保守しやすくなります。
test('successful login redirects to dashboard', async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.goto();
await loginPage.fillEmail('alice@example.com');
await loginPage.fillPassword('password123');
await loginPage.submit();
await expect(page).toHaveURL('/dashboard');
await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible();
});バリデーションエラーのテスト
不正なデータや空のデータで送信し、UIに表示されるエラーメッセージをアサートします。
test('shows validation errors on empty submit', async ({ page }) => {
await page.goto('/register');
await page.getByRole('button', { name: 'Create account' }).click();
await expect(page.getByText('Email is required')).toBeVisible();
await expect(page.getByText('Password must be at least 8 characters')).toBeVisible();
});マルチステップフォームのテスト
複数ステップのウィザードでは各ステップを順に進み、フォームが次へ進むことと、以前に入力した内容が保持されることをアサートします。
test('completes 3-step signup', async ({ page }) => {
await page.goto('/signup');
// Step 1
await page.getByLabel('First Name').fill('Alice');
await page.getByRole('button', { name: 'Next' }).click();
// Step 2
await page.getByLabel('Plan').selectOption('pro');
await page.getByRole('button', { name: 'Next' }).click();
// Step 3
await page.getByLabel('Card Number').fill('4242424242424242');
await page.getByRole('button', { name: 'Complete' }).click();
await expect(page.getByText('Welcome, Alice!')).toBeVisible();
});PlaywrightでのAPIモック
page.route()を使用してAPI呼び出しをインターセプトし、モックレスポンスを返します。実際のバックエンドなしでエッジケースをテストする場合に便利です。
await page.route('/api/register', async route => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ token: 'fake-token' }),
});
});
await page.goto('/register');
// ...fill and submit form
await expect(page).toHaveURL('/dashboard');ファイルアップロードのテスト
setInputFiles()を使用して、Playwrightでのファイルアップロードを再現します。
test('uploads a profile photo', async ({ page }) => {
await page.goto('/profile');
const fileInput = page.getByLabel('Profile photo');
await fileInput.setInputFiles('./fixtures/avatar.png');
await page.getByRole('button', { name: 'Upload' }).click();
await expect(page.getByAltText('Profile photo')).toBeVisible();
});認証状態の再利用
一度ログインしてブラウザのストレージ状態を保存し、テスト間で再利用すると、ログインフローの繰り返しを省略できます。
// auth.setup.ts
test('authenticate', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Email').fill('alice@example.com');
await page.getByLabel('Password').fill('password');
await page.getByRole('button', { name: 'Log in' }).click();
await page.context().storageState({ path: 'e2e/.auth/user.json' });
});
// playwright.config.ts — use storageState in other tests
use: { storageState: 'e2e/.auth/user.json' }エラーからの復旧のテスト
ネットワーク障害を再現し、ユーザーが再試行できること、または役立つエラーメッセージが表示されることを確認します。
await page.route('/api/submit', route => route.abort());
await page.getByRole('button', { name: 'Submit' }).click();
await expect(page.getByText('Network error. Please try again.')).toBeVisible();
await page.unroute('/api/submit');
// Now the real request goes through
await page.getByRole('button', { name: 'Retry' }).click();キーボードナビゲーションのテスト
フィールド間をTabキーで移動し、Enterキーで送信して、フォーム全体がキーボードで操作できることをテストします。
test('submits form with keyboard only', async ({ page }) => {
await page.goto('/contact');
await page.keyboard.press('Tab'); // focus name
await page.keyboard.type('Alice');
await page.keyboard.press('Tab'); // focus email
await page.keyboard.type('alice@example.com');
await page.keyboard.press('Tab'); // focus submit
await page.keyboard.press('Enter');
await expect(page.getByText('Message sent!')).toBeVisible();
});テストデータ用のフィクスチャ
Playwrightのフィクスチャを使用して、テストユーザーの作成などのセットアップ処理を複数のテスト間で適切に共有します。
// fixtures.ts
const test = base.extend<{ testUser: User }>({
testUser: async ({}, use) => {
const user = await createTestUser();
await use(user);
await deleteTestUser(user.id);
},
});
// In a test file:
test('edits profile', async ({ page, testUser }) => {
await page.goto(`/users/${testUser.id}/edit`);
});テストの並列実行
Playwrightはデフォルトでワーカー間のテストを並列実行します。順番に実行する必要があるテストに限り、test.describe.serialを使用してください。
クイックチェック
E2Eテストにおけるページオブジェクトモデル(POM)の主な利点は何でしょうか。
振り返り
E2Eフォームテストでは保守性のためにページオブジェクトを使用し、APIモックにはpage.route()を、アップロードにはsetInputFiles()を使用します。ストレージ状態を使うと認証セッションを再利用できます。バリデーション、複数ステップのフロー、キーボードナビゲーションをテストして、実際のユーザージャーニーを網羅してください。
AI チューターと学ぶ React — 無料
ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。
- コース
- 88
- レッスン
- 324
よくある質問
「フォームとユーザーフローのE2Eテスト」レッスンは無料ですか?
はい。「フォームとユーザーフローのE2Eテスト」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。
「フォームとユーザーフローのE2Eテスト」で何を学びますか?
Playwrightのpage objectsで、複数ステップのフォーム送信とナビゲーションフローを自動化します。 ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
React Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「フォームとユーザーフローのE2Eテスト」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このReact Academyレッスンでコードを書いて実行できますか?
はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- React Testing LibraryによるIntegration Testing
- MSWによる非同期UIとAPI呼び出しのテスト
- React向けPlaywright入門
- フォームとユーザーフローのE2Eテスト