PlaywriteでE2Eテストを試す
playwright について
Playwrightはマイクロソフトが中心となって開発しているオープンソースのWebアプリケーション向けテスト自動化フレームワークです。Chrome、Safari、Firefox、Edgeに加えて、タッチデバイスのモバイル端末の検証も行えます。
課題
これまで selenium に始まり nightwatch > webdriver.io > testcafe > cypress と渡り歩き、playwright の評判が割りと良さそうだったので乗り換えてみることにした。どのツールでも常にテスト実行時の安定性、メンテナンス性、操作性、実行速度、レポートなどに課題があったように思える。結果的に運用保守にまで至っておらず自己満足で終わることが多い。
目的
- サクッと環境を構築できる
- テストケースを誰でも作成できる
- メンテナンスが容易になる
- テストの自動化ができる
- プロダクトの運用保守にのせる
- IDEに統合する
インストール
$ npm init playwright@latest
テストケースの自動生成
以下のコマンドで検証対象のページが立ち上がる。操作を行うと内容のコードを生成してくれる。
$ npx playwright codegen "http://localhost:3000/"
コードを保存
生成されたコードを整形して playwrite/hoge.spec.ts に保存
実行
// UIなし
$ npx playwright test
// UIあり
$ npx playwright test --ui
レポート
実行結果の内容を見たい場合はこちら
$ npx playwright show-report
Q&A集
Q. 画面遷移直後のローディング時にスクリーンショットが実行され画面が不完全
A. ローディングアイコンが非表示になったらなどの条件を設定する。
await page.waitForSelector('.loading', { state: 'hidden' });
await page.screenshot({ path: `screenshot.png`, fullPage: true });
Q. テスト中にタイムアウトしてしまう
Error: locator.waitFor: Test timeout of 30000ms exceeded.
A. 上記のエラーが出る場合はデフォルトのタイムアウト時間が効いている。
設定ファイルでタイムアウトの時間を伸ばす
export default defineConfig({
...
timeout: 2 * 60 * 1000, // デフォルトは30秒
...
});
Q. 検証対象のブラウザを編集したい
A. 設定ファイルで変更する
export default defineConfig({
// 使用するブラウザを指定
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
});
Q. 画面サイズを変更したい
A. playwrite.config.ts の ブラウザの設定ごとに記述可能。ちなみにviewportが小さすぎると画面外のボタンがクリックできずに失敗することがある。
projects: [
{
name: 'chromium',
use: {
..
viewport: { width: 640, height: 480 },
},
},
Q. アニメーション中にスクリーンショットをしてしまう
A. スクリーンショットのオプションでアニメーションを無効化する
await page.screenshot({
animations: "disabled"
});
Q. ページ内で開かれた別タブ、別ウィンドウをスクリーンショットしたい
A. ページを開くイベントを待って、スクリーンショットを取り、ウィンドウを閉じる
// 例)
await page.getByText('外部リンクのページ').click();
// ページが開くまで待つ
const tab = await page.context().waitForEvent('page');
// ページの読み込みが完了するまで待つ(外部ページの場合でpushを使用している場合などは注意が必要)
await tab.waitForLoadState("networkidle");
// スクリーンショットを取る
await tab.screenshot({ path: `screenshots/newTab.png` });
// タブを閉じる
await tab.close();
Q. CIツールでテストを自動化したい
一般的にはGithub Actionsを使うのだろうが、当社は Jetbrains Spaceでビルド環境を構築する予定なので、ビルド時に自動的に実行するようにしたい。
Q. スクリーンショットの差分を確認したい
うまく動いてない。
Q. スクロールしてスクリーンショットを取りたい
Q. 要素の選択方法いろいろ
通常
その他Q. エラー時のレポート表示不要
A. 設定ファイルで指定可能
export default defineConfig({
reporter: 'html',
↓
reporter: [ ['html', { open: 'never' }] ],
}
Q. レポートを見やすくしたい
https://zenn.dev/koheii/articles/2ec38ffbd33ca4
Q. テストを分割したい
ログイン・ログアウトなどは共通化し、各画面や機能ごとにテストを分割したい。
あるいはテストする対象を絞り込みたい。