O hirunewani blog

Q. Playwrightのテスト改善をしてほしい

Created at

Playwrightのテスト改善をしてほしいという相談を受けた際の対応をまとめた。

状況

PlaywrightをWebkit/ChromeのDesktop/Mobileデバイスに対して実行し、Github ActionsのUbuntu latest上で計160個のテストが30分以上かけて実行されていた。

実行ステータスがFailedになっており、ログを確認するとエラーが大量に出ている。

ただしローカルで実行しても失敗することはあるが、8割方成功する。

対応

Playwright reportを確認する

Github Actions上でPlaywright reportがArtifactにアップロードされていたので、それを確認した。

- run: yarn playwright install --with-deps
- run: yarn playwright test
- uses: actions/upload-artifact@v3
  if: always()
  with:
    name: playwright-report
    path: playwright-report/
    retention-days: 30

次のような状態になっていた。

  • Faile:7個以上
    • ほとんどはWebkit、特にMobile Webkit
  • Flaky:10個以上

Failedしているテストに加えてFlakyなテストが多いことや、テストによっては実行する必要がない環境で実行されているテストが複数あることで、実行時間がとても長くなっていた。

実行されるデバイスを制限する

Mobileでのみ、Chromeでのみ実行されることが前提のコードのテストコードがいくつかあったため、適切にスキップされるようにした。

test.beforeEach(async ({ browserName, isMobile }) => {
  test.skip(browserName === "webkit");
  test.skip(isMobile);
});

Flakyテストを改善する

テストコードで前提となる状態を待たずに、次の操作を行っている箇所が多くあった。

  • ページ遷移などにかかる時間もDOMの操作に掛かってしまうため落ちやすくなっていた。
  await page.getByRole("button", { name: "次へ" }).click();
  await page.getByText("パスポートをアップロード").click();

+ await page.waitForURL(`${BASE_URL}/guests/**/identification-image`);
  const button = page.getByRole("button", { name: "次へ" });
+ await expect(button).not.toBeDisabled();
  await button.click();
+ await page.waitForURL(`${BASE_URL}/complete`);

この対応で、Flakyテストはほぼ発生しなくなり、Chromeではテストが落ちなくなった。

Webkit環境が異様に遅い

ページ遷移でのタイムアウトがどうしても改善しない箇所がある。

  • Github Actions(Ubuntu latest)で発生、ローカルでは発生しない。
  • Webkitでのみ発生する。

Webkit環境のテストはMacOSでのみ実行する

Linux及びWebkitでの組み合わせのバグを踏んでいると考え、WebkitのみMacOSでのみ実行するように変更すると、テストが安定するようになった。

// playwright.config.js
{
  projects: [
    {
      name: "Mobile Chrome",
      use: { ...devices["Pixel 5"], permissions: ["microphone", "camera"] },
    },
    process.platform === "darwin"
      ? {
          name: "Mobile Safari",
          use: { ...devices["iPhone 12"] },
        }
      : {},
  ];
}
name: Playwright tests on release pull requests
on:
  pull_request:
    branches: [deploy]

jobs:
  test:
    timeout-minutes: 60
    runs-on: macos-latest

比較

今まで→ Flakyテストの改善→ デバイス制限後→ リリースPR
OSUbuntuUbuntuUbuntuMacOS
ブラウザSafari/ChromeSafari/ChromeChromeのみSafari/Chrome
実行時間25~30m17m7m15m
Flakyテスト10個以上1~3個0個0個
Failedテスト7個以上6個0個0個