E2E テスト
ルール
- PlaywrightをE2Eに使用 — クロスブラウザ、自動待機、組み込みテストランナー、優れたCIサポート
- ロケーターの優先順位:
getByRole() > getByLabel() > getByPlaceholder() > getByTestId() > CSSセレクタ
- ページオブジェクトモデル: ページ操作をクラスにカプセル化 —
LoginPage.login(email, password)
- テスト分離: 各テストは新しい状態で開始 — セットアップには
beforeEach を使用し、テスト間の依存を避ける
- 自動待機: Playwrightは自動的に要素を待機 — 手動で
waitForTimeout() を追加しない
- アサーション:
expect(locator) のWebファーストアサーションを使用 — toBeVisible(), toHaveText(), toHaveURL()
- 並列実行: テストはデフォルトで並列実行 — テスト間で共有可変状態を持たないようにする
- CI: ヘッドレスモードで実行、リトライを設定(CIでは
retries: 2)、失敗時にトレースをアップロード
- ビジュアルリグレッション:
expect(page).toHaveScreenshot() — --update-snapshots でベースラインを更新
パターン
class LoginPage {
constructor(private page: Page) {}
async goto() { await this.page.goto("/login"); }
async login(email: string, password: string) {
await this.page.getByLabel("メールアドレス").fill(email);
await this.page.getByLabel("パスワード").fill(password);
await this.page.getByRole("button", { name: "サインイン" }).click();
await this.page.waitForURL("/dashboard");
}
}
export default defineConfig({
retries: process.env.CI ? 2 : 0,
use: { trace: "on-first-retry", screenshot: "only-on-failure" },
projects: [
{ name: "chromium", use: { ...devices["Desktop Chrome"] } },
{ name: "mobile", use: { ...devices["Pixel 5"] } },
],
});
避けるべきこと
page.waitForTimeout() — 代わりに自動待機または waitForURL(), waitForResponse() を使用
- インタラクティブ要素に対するCSSセレクタ — ロールベースのロケーターを使用して堅牢性を向上
- 他のテストの状態に依存するテスト — 各テストは独立して実行可能でなければならない
- サードパーティサービスを直接テスト —
page.route() で外部APIをモックする
- モバイルビューポートをスキップ — プロジェクトマトリックスに少なくとも1つのモバイルデバイスを含める