メインコンテンツにスキップ

ベストプラクティス

はじめに

このガイドは、ベストプラクティスに従い、より回復力のあるテストを作成するのに役立ちます。

テストの哲学

ユーザーに見える動作をテストする

自動テストは、アプリケーションコードがエンドユーザー向けに動作することを検証し、ユーザーが通常使用、閲覧、または認識しない実装の詳細(関数の名前、何かが配列であるかどうか、または一部の要素の 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');

データベースを使用したテスト

データベースを操作する場合は、データを制御していることを確認してください。ステージング環境に対してテストし、変更されないことを確認してください。ビジュアルリグレッションテストの場合は、オペレーティングシステムとブラウザのバージョンが同じであることを確認してください。

ベストプラクティス

ロケーターを使用する

エンドツーエンドテストを作成するには、まず Web ページ上の要素を見つける必要があります。これは、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 を実行します。

npx playwright codegen playwright.dev

これにより、新しいブラウザウィンドウと Playwright インスペクターが開きます。ロケーターを選択するには、まず「Record」ボタンをクリックして記録を停止します。デフォルトでは、codegen コマンドを実行すると、新しい記録が開始されます。記録を停止すると、「Pick Locator」ボタンをクリックできるようになります。

次に、ブラウザウィンドウのページの任意の要素にカーソルを合わせると、カーソルの下にロケーターが強調表示されます。要素をクリックすると、ロケーターが Playwright インスペクターに追加されます。ロケーターをコピーしてテストファイルに貼り付けるか、Playwright インスペクターでテキストを変更するなどしてロケーターを探索し続け、ブラウザウィンドウで結果を確認できます。

generating locators with codegen

VS Code 拡張機能を使用してロケーターを生成する

VS Code 拡張機能を使用して、ロケーターを生成したり、テストを記録したりすることもできます。VS Code 拡張機能は、テストの作成、実行、デバッグ時にも優れた開発者エクスペリエンスを提供します。

generating locators in vs code with codegen

Web ファーストアサーションを使用する

アサーションは、期待される結果と実際の結果が一致するかどうかを検証する方法です。Web ファーストアサーションを使用すると、Playwright は期待される条件が満たされるまで待機します。たとえば、アラートメッセージをテストする場合、テストはメッセージを表示するボタンをクリックし、アラートメッセージがあることを確認します。アラートメッセージが表示されるまでに 0.5 秒かかる場合、toBeVisible() などのアサーションは必要に応じて待機して再試行します。

// 👍
await expect(page.getByText('welcome')).toBeVisible();

// 👎
expect(await page.getByText('welcome').isVisible()).toBe(true);

手動アサーションを使用しない

expect を待機していない手動アサーションは使用しないでください。以下のコードでは、await は expect の前にではなく、expect の内側にあります。isVisible() などのアサーションを使用すると、テストは 1 秒も待機せず、ロケーターがあるかどうかを確認してすぐに戻ります。

// 👎
expect(await page.getByText('welcome').isVisible()).toBe(true);

代わりに、toBeVisible() などの Web ファーストアサーションを使用してください。

// 👍
await expect(page.getByText('welcome')).toBeVisible();

デバッグを設定する

ローカルデバッグ

ローカルデバッグの場合、VSCode でテストをライブデバッグすることをお勧めします。VS Code 拡張機能をインストールします。実行するテストの横の行を右クリックしてデバッグモードでテストを実行できます。これにより、ブラウザウィンドウが開き、ブレークポイントが設定されている場所で一時停止します。

debugging tests in vscode

VS Code でテストのロケーターをクリックまたは編集してテストをライブデバッグできます。これにより、ブラウザウィンドウでこのロケーターが強調表示され、ページで見つかった他のすべての一致するロケーターも表示されます。

live debugging locators in vscode

--debug フラグを指定してテストを実行することにより、Playwright インスペクターでテストをデバッグすることもできます。

npx playwright test --debug

次に、テストをステップ実行し、操作可能性ログを表示し、ロケーターをライブで編集して、ブラウザウィンドウで強調表示されているのを確認できます。これにより、どのロケーターが一致するか、それらがいくつあるかがわかります。

debugging with the playwright inspector

特定のテストをデバッグするには、テストファイルの名前とテストの行番号に続けて --debug フラグを追加します。

npx playwright test example.spec.ts:9 --debug

CI でのデバッグ

CI の失敗の場合は、動画やスクリーンショットの代わりに Playwright トレースビューワーを使用してください。トレースビューワーは、ローカルのプログレッシブウェブアプリ(PWA)としてテストの完全なトレースを提供し、簡単に共有できます。トレースビューワーを使用すると、タイムラインを表示したり、開発ツールを使用して各アクションの DOM スナップショットを検査したり、ネットワークリクエストなどを表示したりできます。

playwrights trace viewer

トレースは Playwright 設定ファイルで構成されており、失敗したテストの最初のリトライで実行するように設定されています。トレースがすべてのテストで実行されるようにこれを on に設定することはお勧めしません。これは非常にパフォーマンスに負荷がかかるためです。ただし、--trace フラグを使用して開発中にローカルでトレースを実行できます。

npx playwright test --trace on

このコマンドを実行すると、各テストのトレースが記録され、HTML レポートから直接表示できます。

npx playwright show-report
Playwrights HTML report

トレースは、テストファイル名の横にあるアイコンをクリックするか、各テストレポートを開いてトレースセクションまでスクロールすることで開くことができます。

Screenshot 2023-01-13 at 09 58 34

Playwright のツールを使用する

Playwright には、テストの作成に役立つさまざまなツールが付属しています。

  • VS Code 拡張機能は、テストの作成、実行、デバッグ時に優れた開発者エクスペリエンスを提供します。
  • テストジェネレーターは、テストを生成し、ロケーターを選択できます。
  • トレースビューワーは、ローカル PWA としてテストの完全なトレースを提供し、簡単に共有できます。トレースビューワーを使用すると、タイムラインを表示したり、各アクションの DOM スナップショットを検査したり、ネットワークリクエストなどを表示したりできます。
  • UI モードを使用すると、タイムトラベルエクスペリエンスとウォッチモードを備えたテストを探索、実行、デバッグできます。すべてのテストファイルはテストサイドバーにロードされ、各ファイルと describe ブロックを展開して、各テストを個別に実行、表示、監視、およびデバッグできます。
  • Playwright の TypeScript はすぐに使用でき、IDE の統合が向上します。IDE は、実行できるすべてのことを表示し、何か間違ったことを行うと強調表示します。TypeScript の経験は必要ありません。コードが TypeScript で記述されている必要はありません。必要なのは、.ts 拡張子でテストを作成することだけです。

すべてのブラウザでテストする

Playwright を使用すると、プラットフォームに関係なく、すべてのブラウザでサイトを簡単にテストできます。すべてのブラウザでテストすることで、アプリがすべてのユーザーに対して動作することが保証されます。設定ファイルで、名前と使用するブラウザまたはデバイスを追加してプロジェクトを設定できます。

playwright.config.ts
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 install -D @playwright/test@latest

リリースノートを確認して、最新バージョンとリリースされた変更内容を確認してください。

次のコマンドを実行して、Playwright のバージョンを確認できます。

npx playwright --version

CI でテストを実行する

CI/CD をセットアップし、テストを頻繁に実行します。テストの実行頻度が高いほど、より良いです。理想的には、コミットごとおよびプルリクエストごとにテストを実行する必要があります。Playwright には、GitHub actions ワークフローが付属しているため、セットアップなしで CI でテストを実行できます。Playwright は、選択したCI 環境にもセットアップできます。

CI でテストを実行する場合は、Linux を使用してください。安価です。開発者はローカルで実行する場合はどのような環境でも使用できますが、CI では Linux を使用してください。CI を高速化するためにシャーディングの設定を検討してください。

CI でのブラウザのダウンロードを最適化する

特に CI では、実際に必要なブラウザのみをインストールしてください。たとえば、Chromium のみでテストする場合は、Chromium のみをインストールしてください。

.github/workflows/playwright.yml
# Instead of installing all browsers
npx playwright install --with-deps

# Install only Chromium
npx playwright install chromium --with-deps

これにより、CI マシンでのダウンロード時間とディスク容量の両方が節約されます。

テストをリントする

テストで TypeScript と ESLint によるリントを使用して、エラーを早期にキャッチすることをお勧めします。@typescript-eslint/no-floating-promises ESLint ルールを使用して、Playwright API への非同期呼び出しの前に await が欠落していないことを確認してください。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 は、テストスイートをシャーディングして、複数のマシンで実行できるようにすることができます。

npx playwright test --shard=1/3

生産性のヒント

ソフトアサーションを使用する

テストが失敗した場合、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();