ベストプラクティス
はじめに
このガイドは、Playwright のベストプラクティスに従い、より回復力のあるテストを作成するのに役立ちます。
テストの哲学
ユーザーに表示される動作をテストする
自動テストは、アプリケーションコードがエンドユーザーに対して機能することを確認し、ユーザーが通常使用したり、見たり、知ったりすることのない実装の詳細(関数名、配列であるかどうか、要素のCSSクラスなど)に依存することを避けるべきです。エンドユーザーはページにレンダリングされたものを見たり操作したりするので、テストも通常、同じレンダリングされた出力のみを見たり操作したりするべきです。
テストを可能な限り分離する
各テストは他のテストから完全に分離され、独自のローカルストレージ、セッションストレージ、データ、Cookieなどを使って独立して実行されるべきです。テストの分離は再現性を向上させ、デバッグを容易にし、連鎖的なテストの失敗を防ぎます。
テストの特定の部分での繰り返しを避けるために、before/after フックを使用できます。テストファイル内で、特定のURLにアクセスしたり、アプリの一部にログインしたりするなど、各テストの前にテストの一部を実行するためのbeforeフックを追加します。これにより、テストが相互に依存しないため、テストが分離されます。ただし、テストが十分にシンプルで、テストがより明確で読みやすく、保守しやすい状態を保つのであれば、多少の重複があっても問題ありません。
import { test } from '@playwright/test';
test.beforeEach(async ({ page }) => {
// Runs before each test and signs in each page.
await page.goto('https://github.com/login');
await page.getByLabel('Username or email address').fill('username');
await page.getByLabel('Password').fill('password');
await page.getByRole('button', { name: 'Sign in' }).click();
});
test('first', async ({ page }) => {
// page is signed in.
});
test('second', async ({ page }) => {
// page is signed in.
});
セットアッププロジェクトを使用すると、ログイン状態をテストで再利用することもできます。これにより、一度ログインするだけで、すべてのテストでログイン手順をスキップできます。
サードパーティの依存関係のテストを避ける
自分が制御できるものだけをテストしてください。制御できない外部サイトやサードパーティサーバーへのリンクをテストしようとしないでください。それは時間がかかり、テストを遅くするだけでなく、リンク先のページの内容や、Cookieバナーやオーバーレイページなど、テストを失敗させる可能性のあるものを制御できないためです。
代わりに、Playwright Network APIを使用し、必要な応答を保証してください。
await page.route('**/api/fetch_data_third_party_dependency', route => route.fulfill({
status: 200,
body: testData,
}));
await page.goto('https://example.com');
データベースを使ったテスト
データベースを使用する場合は、データを制御していることを確認してください。ステージング環境に対してテストを行い、変更されないようにしてください。ビジュアルリグレッションテストの場合は、オペレーティングシステムとブラウザのバージョンが同じであることを確認してください。
ベストプラクティス
ロケーターを使用する
エンドツーエンドテストを作成するには、まずウェブページ上の要素を見つける必要があります。これには、Playwrightに組み込まれているロケーターを使用できます。ロケーターには自動待機とリトライ機能があります。自動待機とは、Playwrightがクリックを実行する前に、要素が表示され、有効になっていることを確認するなど、要素に対するさまざまなアクション可能性チェックを実行することを意味します。テストの回復力を高めるために、ユーザーに表示される属性と明示的な契約を優先することをお勧めします。
// 👍
page.getByRole('button', { name: 'submit' });
チェイニングとフィルタリングを使用する
ロケーターはチェイニングすることで、ページの特定の部分に検索を絞り込むことができます。
const product = page.getByRole('listitem').filter({ hasText: 'Product 2' });
また、テキストまたは別のロケーターでロケーターをフィルタリングすることもできます。
await page
.getByRole('listitem')
.filter({ hasText: 'Product 2' })
.getByRole('button', { name: 'Add to cart' })
.click();
XPath や CSS セレクターよりもユーザーに表示される属性を優先する
DOMは簡単に変更されるため、DOM構造に依存するテストは失敗につながる可能性があります。たとえば、CSSクラスでこのボタンを選択することを考えてみてください。デザイナーが何かを変更すると、クラスが変更され、テストが壊れる可能性があります。
// 👎
page.locator('button.buttonIcon.episode-actions-later');
DOMの変更に強いロケーターを使用してください。
// 👍
page.getByRole('button', { name: 'submit' });
ロケーターを生成する
Playwright には、テストを生成し、ロケーターを自動で選択してくれるテストジェネレーターがあります。ページを分析し、最適なロケーター(役割、テキスト、テストIDロケーターを優先)を判断します。ジェネレーターがロケーターに一致する複数の要素を見つけた場合、そのロケーターを改善して、ターゲット要素を一意に識別できるようにするため、ロケーターが原因でテストが失敗する心配はありません。
codegen を使用してロケーターを生成する
ロケーターを選択するには、codegen コマンドの後に、ロケーターを選択したいURLを入力して実行します。
- npm
- yarn
- pnpm
npx playwright codegen playwright.dev
yarn playwright codegen playwright.dev
pnpm exec playwright codegen playwright.dev
これにより、新しいブラウザウィンドウと Playwright インスペクターが開きます。ロケーターを選択するには、まず「Record」ボタンをクリックして録画を停止します。デフォルトでは、codegen コマンドを実行すると、新しい録画が開始されます。録画を停止すると、「Pick Locator」ボタンがクリックできるようになります。
その後、ブラウザウィンドウ内の任意の要素にカーソルを合わせると、カーソルの下にロケーターがハイライト表示されます。要素をクリックすると、Playwright インスペクターにロケーターが追加されます。ロケーターをコピーしてテストファイルに貼り付けることも、Playwright インスペクターでテキストを変更するなどしてロケーターを編集し、ブラウザウィンドウで結果を確認することもできます。
VS Code 拡張機能を使用してロケーターを生成する
VS Code 拡張機能を使用すると、ロケーターの生成だけでなく、テストの記録もできます。VS Code 拡張機能は、テストの作成、実行、デバッグにおいても優れた開発者エクスペリエンスを提供します。
Web ファーストアサーションを使用する
アサーションは、期待される結果と実際の結果が一致したかどうかを検証する方法です。Webファーストアサーションを使用すると、Playwrightは期待される条件が満たされるまで待機します。たとえば、アラートメッセージをテストする場合、テストはメッセージが表示されるボタンをクリックし、アラートメッセージが存在することを確認します。アラートメッセージが表示されるのに0.5秒かかる場合、toBeVisible()などのアサーションは必要に応じて待機して再試行します。
// 👍
await expect(page.getByText('welcome')).toBeVisible();
// 👎
expect(await page.getByText('welcome').isVisible()).toBe(true);
手動アサーションを使用しない
expect を待機しない手動アサーションを使用しないでください。以下のコードでは、await は expect の前ではなく、中にあります。isVisible() のようなアサーションを使用する場合、テストは1秒も待たず、ロケーターが存在するかどうかをチェックしてすぐに返します。
// 👎
expect(await page.getByText('welcome').isVisible()).toBe(true);
代わりに、toBeVisible() などの Web ファーストアサーションを使用してください。
// 👍
await expect(page.getByText('welcome')).toBeVisible();
デバッグを設定する
ローカルデバッグ
ローカルデバッグの場合、VS Code 拡張機能をインストールして、VSCode でライブデバッグすることをお勧めします。実行したいテストの行の隣を右クリックしてデバッグモードでテストを実行すると、ブラウザウィンドウが開き、ブレークポイントが設定されている場所で一時停止します。
VS Code でテスト内のロケーターをクリックまたは編集することで、テストをライブデバッグできます。これにより、ブラウザウィンドウでそのロケーターが強調表示され、ページ上で見つかった他のすべての一致するロケーターも表示されます。
また、--debug フラグを付けてテストを実行することで、Playwright インスペクターを使用してテストをデバッグすることもできます。
- npm
- yarn
- pnpm
npx playwright test --debug
yarn playwright test --debug
pnpm exec playwright test --debug
そうすることで、テストをステップ実行し、アクションログを表示し、ロケーターをライブで編集してブラウザウィンドウでハイライト表示されるのを確認できます。これにより、どのロケーターが一致し、いくつあるかがわかります。
特定のテストをデバッグするには、テストファイルの名前とテストの行番号の後に --debug フラグを追加します。
- npm
- yarn
- pnpm
npx playwright test example.spec.ts:9 --debug
yarn playwright test example.spec.ts:9 --debug
pnpm exec playwright test example.spec.ts:9 --debug
CI でのデバッグ
CI の失敗については、動画やスクリーンショットの代わりに Playwright のトレースビューアーを使用してください。トレースビューアーは、テストの完全なトレースを、簡単に共有できるローカルのプログレッシブウェブアプリ (PWA) として提供します。トレースビューアーを使用すると、タイムラインの表示、開発者ツールを使用した各アクションの DOM スナップショットの検査、ネットワークリクエストの表示などを行うことができます。
トレースは Playwright の設定ファイルで構成され、失敗したテストの最初のリトライ時に CI で実行されるように設定されています。パフォーマンスに大きな負荷がかかるため、すべてのテストでトレースが実行されるように on に設定することはお勧めしません。ただし、開発時に --trace フラグを使用してローカルでトレースを実行することは可能です。
- npm
- yarn
- pnpm
npx playwright test --trace on
yarn playwright test --trace on
pnpm exec playwright test --trace on
このコマンドを実行すると、各テストのトレースが記録され、HTMLレポートから直接表示できます。
- npm
- yarn
- pnpm
npx playwright show-report
yarn playwright show-report
pnpm exec playwright show-report
トレースは、テストファイル名の横にあるアイコンをクリックするか、各テストレポートを開いてトレースセクションまでスクロールすることで開くことができます。
Playwright のツールを使用する
Playwright には、テスト作成を支援するさまざまなツールが付属しています。
- VS Code 拡張機能は、テストの記述、実行、デバッグにおいて優れた開発者体験を提供します。
- テストジェネレーターは、テストを生成し、ロケーターを自動で選択してくれます。
- トレースビューアーは、テストの完全なトレースを、簡単に共有できるローカルの PWA として提供します。トレースビューアーを使用すると、タイムラインの表示、各アクションの DOM スナップショットの検査、ネットワークリクエストの表示などを行うことができます。
- UI モードでは、ウォッチモードを完備したタイムトラベル体験で、テストの探索、実行、デバッグができます。すべてのテストファイルはテストサイドバーに読み込まれ、各ファイルと describe ブロックを展開して、個別に各テストを実行、表示、監視、デバッグできます。
- Playwright のTypeScriptはすぐに使え、IDE との統合が向上します。IDE は、できることすべてを表示し、誤った操作があった場合は強調表示します。TypeScript の経験は不要で、コードが TypeScript である必要もありません。必要なのは、
.ts拡張子でテストを作成することだけです。
すべてのブラウザでテストする
Playwright を使用すると、どのプラットフォームにいても、すべてのブラウザでサイトを簡単にテストできます。すべてのブラウザでテストすることで、アプリがすべてのユーザーに対して機能することを保証します。設定ファイルで、名前と使用するブラウザまたはデバイスを追加してプロジェクトを設定できます。
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
});
Playwright の依存関係を最新の状態に保つ
Playwright のバージョンを最新に保つことで、最新のブラウザバージョンでアプリをテストし、最新のブラウザバージョンが一般公開される前に障害を検出することができます。
- npm
- yarn
- pnpm
npm install -D @playwright/test@latest
yarn add --dev @playwright/test@latest
pnpm install --save-dev @playwright/test@latest
リリースノートで最新バージョンとリリースされた変更点を確認してください。
以下のコマンドを実行すると、Playwright のバージョンを確認できます。
- npm
- yarn
- pnpm
npx playwright --version
yarn playwright --version
pnpm exec playwright --version
CI でテストを実行する
CI/CD を設定し、頻繁にテストを実行してください。テストを実行する頻度が高いほど良いです。理想的には、コミットやプルリクエストごとにテストを実行すべきです。Playwright にはGitHub Actions ワークフローが付属しているため、設定なしで CI でテストが実行されます。Playwright は、選択したCI 環境でも設定できます。
CI でテストを実行する際は、費用が安いため Linux を使用してください。開発者はローカルで実行する際はどのような環境でも使用できますが、CI では Linux を使用してください。シャーディングを設定して CI を高速化することを検討してください。
CI でのブラウザダウンロードを最適化する
特に CI では、実際に必要なブラウザのみをインストールしてください。たとえば、Chromium のみでテストする場合は、Chromium のみをインストールします。
# Instead of installing all browsers
npx playwright install --with-deps
# Install only Chromium
npx playwright install chromium --with-deps
これにより、CI マシンでのダウンロード時間とディスクスペースの両方を節約できます。
テストをLintする
エラーを早期に検出するために、TypeScript と ESLint によるテストのリンティングをお勧めします。Playwright API への非同期呼び出しの前に await が欠落していないことを確認するために、@typescript-eslint/no-floating-promises ESLint ルールを使用してください。CI では、tsc --noEmit を実行して、関数が正しいシグネチャで呼び出されていることを確認できます。
並列処理とシャーディングを使用する
Playwright はデフォルトでテストを並行して実行します。単一ファイル内のテストは、同じワーカープロセスで順番に実行されます。単一ファイルに多くの独立したテストがある場合は、それらを並行して実行したい場合があります。
import { test } from '@playwright/test';
test.describe.configure({ mode: 'parallel' });
test('runs in parallel 1', async ({ page }) => { /* ... */ });
test('runs in parallel 2', async ({ page }) => { /* ... */ });
Playwright はテストスイートをシャード分割できるため、複数のマシンで実行できます。
- npm
- yarn
- pnpm
npx playwright test --shard=1/3
yarn playwright test --shard=1/3
pnpm exec playwright test --shard=1/3
生産性向上TIPS
ソフトアサーションを使用する
テストが失敗した場合、Playwright はテストのどの部分が失敗したかを示すエラーメッセージを、VS Code、ターミナル、HTML レポート、またはトレースビューアーで表示します。ただし、ソフトアサーションを使用することもできます。これらはテストの実行をすぐに終了せず、テストが終了した後に失敗したアサーションのリストをコンパイルして表示します。
// Make a few checks that will not stop the test when failed...
await expect.soft(page.getByTestId('status')).toHaveText('Success');
// ... and continue the test to check more things.
await page.getByRole('link', { name: 'next page' }).click();