はじめに
システムの品質向上を考える時にユーザーにサービスを正しく提供できているか?という観点は重要な要素になってきます。
フロントエンド開発におけるテストとしてこれまでJestを使ったユニットテストやReact Testing LibraryによるUIコンポーネントテストをご紹介してきました。
これだけでユーザーにサービスを正しく提供できていると担保できるかというとそうでもありません。
実際は各種バックエンドサービス(API、外部ストレージなど)との連携の上で多くのシステムは成り立っています。
そのため、それらを含めたシステム全体のテストを今回はPlaywrightを使って実装していきます。
E2Eテストとは
E2Eテスト(エンドツーエンドテスト)とは、アプリケーション全体の流れをユーザー視点でテストする方法です。
ユーザーがシステムをどのように操作するかを再現し、実際の操作に近い環境でシステム全体の挙動を確認することを目的としています。
具体的には、ログイン、データ入力、ページ遷移、データの保存や読み込みといった一連の操作をテストし、それらが意図した通りに動作するかどうかを検証します。
E2Eテストのメリット:
- 実ユーザー視点
ユーザーの体験に近いテストができ、ユーザーにとっての問題を事前に検知しやすくなります。 - システム全体の確認
フロントエンドからバックエンド、そしてデータベースまで含めたシステム全体の動作確認が可能です。 - バグの早期発見
各機能が統合された状態での問題を早期に発見することで、リリース前のクオリティ向上に貢献します。
ただし、E2Eテストは一般的にテストの実行に時間がかかり、環境設定も複雑になる傾向があります。
そのため、必要なケースに絞って適切に管理することが重要です。
Playwrightとは
Playwrightは、Microsoftが開発したオープンソースのエンドツーエンド(E2E)テスト自動化ツールです。
ウェブアプリケーションのテストに特化しており、複数のブラウザ(Chromium、Firefox、WebKitなど)での動作を簡単に確認できるように設計されています。
Playwrightの特徴
-
複数ブラウザ対応
Playwrightは、Chromium(ChromeやEdge)、Firefox、WebKit(Safariのエンジン)など、主要なブラウザをサポートしています。これにより、異なるブラウザ環境でアプリケーションが正しく動作するかを簡単に確認できます。 -
並行テスト実行
Playwrightは、並行してテストを実行する機能があり、大量のテストケースでも高速に実行できるため、開発速度の向上に役立ちます。 -
クロスプラットフォーム
Windows、Mac、Linuxで動作するため、どのOS上でもテストを簡単に実行できます。モバイルブラウザにも対応しているため、デスクトップとモバイルの両方でのテストが可能です。 -
多種多様なAPI
Playwrightは、ページの読み込み完了、ネットワークリクエスト、DOM操作などのイベントを細かく制御できるAPIを提供しており、複雑なユーザーシナリオの再現や、ページ間の遷移、ファイルのアップロード・ダウンロードなども簡単にテストできます。 -
スクリーンショットと動画のキャプチャ
テスト中にスクリーンショットや動画をキャプチャする機能があり、テスト結果の確認やバグ調査をスムーズに行うことができます。
Playwrightのメリット
- 迅速なフィードバック
並行テストやクロスブラウザ対応により、素早くテスト結果を確認できるので、開発スピードの向上に寄与します。 - 信頼性の高さ
ネットワークや画面の状態を制御できるため、特定の条件下でのテストが可能で、エラーの再現性を高められます。 - 簡単なセットアップ
比較的簡単にセットアップでき、デフォルトで様々なブラウザに対応しているため、他のツールに比べて導入コストが低いといえます。
Playwrightはフロントエンド開発者やQAエンジニアがE2Eテストを行うのに便利なツールです。
Playwrightの導入
Playwright公式ドキュメントにインストールの手順がありますのでこちらを参考に進めていきます。
適当なディレクトリで下記のコマンドを実行します。
npm init playwright@latest
すると幾つかの選択肢が登場しますが、基本的にはデフォルトの設定で問題ないのでエンターキーで進めていきインストールします。
- Choose between TypeScript or JavaScript (default is TypeScript)
TypeScriptかJavaScriptのどちらかを選択(デフォルトはTypeScript) - Name of your Tests folder (default is tests or e2e if you already have a tests folder in your project)
Testsフォルダの名前(デフォルトはtests、プロジェクトにtestsフォルダがある場合はe2e) - Add a GitHub Actions workflow to easily run tests on CI
GitHub Actionsワークフローを追加してCI上で簡単にテストを実行(デフォルトはfalse) - Install Playwright browsers (default is true)
Playwrightブラウザをインストール(デフォルトはtrue)
サンプルコードを使ったE2Eテスト
test
フォルダを確認するとサンプルのテストコードが用意されています。
import { test, expect } from '@playwright/test';
test('has title', async ({ page }) => {
await page.goto('https://playwright.dev/');
// Expect a title "to contain" a substring.
await expect(page).toHaveTitle(/Playwright/);
});
test('get started link', async ({ page }) => {
await page.goto('https://playwright.dev/');
// Click the get started link.
await page.getByRole('link', { name: 'Get started' }).click();
// Expects page to have a heading with the name of Installation.
await expect(page.getByRole('heading', { name: 'Installation' })).toBeVisible();
});
テストは2つ用意されています。
-
has title
Playwright公式ドキュメントの最初のページを開くとタイトルに「Playwright」というテキストが存在する -
get started link
Playwright公式ドキュメントの最初のページに「Get started」のリンクが存在し、クリックすると「Installation」というタイトルのページに遷移する
既にテストコードが存在していますので早速テストを実行してみます。
npx playwright test
画面のように「6 passed」と表示されたらOKです。
先ほどは2つのテストがあるとご紹介しましたが実際に動かすとテストは6実行されました。
playwright.config.ts
ファイルを開くと下記の記述を確認できます。
/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
Playwrightのprojects
オプションは、異なるテスト環境や設定で同じテストを実行できるようにするための機能です。
例えば、異なるブラウザ(Chrome、Firefox、WebKit)や異なる端末(デスクトップとモバイル)での動作を一度にテストしたい場合、projectsを使うと簡単に切り替えや設定が可能になります。
これによって、複数の環境でのクロスブラウザテストやデバイステストを効率よく行えます。
今回は2つのテストを3つの異なるブラウザ(Chrome、Firefox、WebKit)で実行したので6回テストが実行されました。
テストコードの作成
テストコードは.test.ts
ファイルまたは.spec.ts
ファイルに直接コードを書くことで動作可能ですが、EXCELのマクロ機能のように実際にブラウザを操作してコードを生成する方法もあります。
今回はコードの生成方法を使ってテストコードを書いてみます。
下記のコマンドを実行すると2つの画面が起動します。
npx playwright codegen
実際に操作するブラウザ
ブラウザを操作することで生成されたコードが表示される画面
ブラウザに「https://playwright.dev/」を入力するとPlaywright公式ドキュメントが表示され、操作内容がコードとして表示されます。
次に同じトップ画面のフッター部分にPlaywrightの「GitHub」へのリンクがありますので、目のマークの「assert visibility」で存在することを確認する処理を操作します。
すると操作内容が記録されますので最終的には下記のようなコードが生成されます。
test('test', async ({ page }) => {
await page.goto('https://playwright.dev/');
await expect(page.getByRole('link', { name: 'GitHub', exact: true })).toBeVisible();
});
以上で「Playwright公式ドキュメントの最初のページを開くと、GitHubへのリンクが表示される」というテストコードが完成しました。
テスト名称を少しわかりやすくして、サンプルのテストコードに貼り付けます。
+ test('has github link', async ({ page }) => {
+ await page.goto('https://playwright.dev/');
+ await expect(page.getByRole('link', { name: 'GitHub', exact: true })).toBeVisible();
+ });
テストコード作成のために立ち上げたブラウザは不要になりましたので、ターミナルで「Ctrl + C」で閉じてください。
最後にテストを実行して正常終了することを確認します。
npx playwright test
テストが9件正常終了したらOKです。
テスト結果レポート
これまでテスト結果はターミナルで確認していましたがレポート出力もされています。
これが有用なのはテストが失敗した時になります。
ということでテストが失敗するケースを作ってからレポートを見ていきたいと思います。
先ほど作成したテストケースでテストが失敗するようにを少し修正しました。
test('has github link', async ({ page }) => {
await page.goto('https://playwright.dev/');
- await expect(page.getByRole('link', { name: 'GitHub', exact: true })).toBeVisible();
+ await expect(page.getByRole('link', { name: 'GitHub1', exact: true })).toBeVisible();
});
「GitHub」というリンク名を「GitHub1」と修正することで存在しないリンクを指定するように変えました。
npx playwright test
テストを実行するとテスト失敗のメッセージを確認できます。
(ターミナルでもどこに問題がるか十分確認できるメッセージが表示されていますが、、、)
6件成功し、3件失敗しています。
レポートサーバーについて
ターミナルに「Serving HTML report at http://localhost:9323. Press Ctrl+C to quit.」と表示され、
実際にブラウザで「http://localhost:9323」にアクセスするとテスト結果のレポートが見れます。
これまでテストが全て成功していた時は「Serving HTML report at http://localhost:9323. Press Ctrl+C to quit.」というメッセージは表示されていませんでした。
これはPlaywrightのデフォルトの挙動で、テストが失敗した時はすぐにレポートを確認できるよう自前のHTTPサーバーをローカル環境で立ち上げレポートを見れるようにしています。
では正常終了した時はレポートが見れないのか?というとそんなことはなくテスト終了時に表示されていた下記のコマンドでレポートサーバーを立ち上げレポートを見ることができます。
npx playwright show-report
とは言え全て正常終了している時にテスト内容をそこまで詳しく見ることはないと思いますのでデフォルトの挙動通りで運用は問題ないかと思います。
レポートの内容について
今回は9件のテストなので失敗したテストがどこかすぐ確認できましたが、多くのテストを実施している場合は右上の「Failed」と書いてあるたぶをクリックすると失敗したテストケースのみにフィルタリングされます。
テスト名称、実行ブラウザ、テストに要した時間が記載されています。
試しにchromium
のエラー詳細を確認してみます。
失敗した箇所が22行目で、エラーの内容としては5000ms(5秒間)のタイムアウトとなっています。
PlaywrightではExpect Timeoutがデフォルトで5秒となっております。
expect
での検証(アサーション)が成功するまで待機する時間の上限が決まっており、例えば、非同期処理や状態変化を確認するテストで、特定の条件が満たされるまで待つ際に、どれだけの時間を許容するかを決めます。
具体的にはUIがロードされるのを待つ、データが非同期で取得されるのを待つなど、特定の状態に達するのを待機するテストで役立ちます。
平たく言えば5秒間「GitHub1」というリンク名を探したけど見つからなかったというエラーになります。
レポートについてはPlaywright標準のレポート以外にも様々なサードパーティ製レポートツールが存在しています。
テスト1回分の結果を見たい場合であればPlaywright標準で十分かと思います。
毎日動かしている場合であればこれまでの傾向把握だったり、或いはGitHub上やMicrosoft Teamsにテスト結果を連動したいなど運用負荷を軽減する際には役に立つかと思います。
さいごに
今回はPlaywrightについてご紹介をしつつ導入方法からE2Eテストの実施までご紹介していきました。
テストコードを生成する方法などを見て頂くとイメージつくかと思いますが内部実装がわからない非エンジニア職の方々でも手軽にテストコードを作成しテストを実施できるツールとなっております。
Webサービスにおいては日々システムが変化していく世界ですのでE2Eテストもそれに合わせて変えていく必要があります。
QAチームやPM、ディレクターなども巻き込んでテストの安定運用が実現できたらシステムの安定運用にもつながるのではないかと考えて筆者も日々啓蒙活動をしております。