📝

Playwright を使ったE2Eテストの導入

2024/12/19に公開

はじめに

この春よりフロントエンドエンジニアとしてキャッシュレス決済サービス「誰でも決済」の開発に携わっております、benzoh です。
そしてこの夏、無事にサービスをリリースすることができました!

この記事では開発開始から今日までに取り組んだことの中で「Playwright を使ったE2Eテストの導入」について共有したいと思います。
特に、QRコードを活用した決済フローのテスト自動化について、実践的な知見を交えながら解説していきます。

なお、本記事は Playwright の基本的な使い方を理解している方、もしくは E2E テストフレームワークの導入を検討されている方を対象としています。Playwright の導入手順や基本的な使い方については、公式ドキュメントをご参照ください。

なぜE2Eテストを導入したのか

フロントエンドエンジニアとして開発を進める中で、手動テストだけでは以下のような課題を感じていました。

  • 繰り返し実行される同じテストパターンによる工数の増大
  • 人的ミスのリスク
  • クロスブラウザテストの負担

これらの課題に対して、Playwright によるテスト自動化は、システム全体を通してエンドユーザーの視点から機能検証できる効果的なソリューションとなりました。
特に新規事業の初期段階から導入することで、以下のような利点を得ることができました。

  • 仕様を可視化できる
  • 開発者が本来の開発業務に専念できる
  • プロジェクトの成長に合わせて段階的にテストを拡充できる

Playwrightの主な特徴

今 E2Eテストを書くなら Playwright一択みたいなところもありますが、選んだ理由としては以下のような点です。

  • クロスブラウザ対応
    • Chromium、Firefox、WebKitの各ブラウザエンジンをサポート
    • モバイルデバイスのエミュレーションも可能
  • 開発者フレンドリー
    • TypeScript のサポート
    • async/await による安定したテスト実行
    • IDE の拡張機能の充実

中でも決済の利用者は完全にスマートフォンからのアクセスを想定しているためモバイルデバイスのエミュレーションは必須でした。

QRコードを介した決済フローのテスト実装

プロジェクトの特徴的な実装として、QRコードを介した決済フローのテストがあります。
省略改変していますが、以下のようなイメージです。

test('QRコード決済フローのテスト', async ({ page }) => {
    // ライブラリをロード
    await page.addScriptTag({
        url: 'https://cdn.jsdelivr.net/npm/qr-scanner@latest/qr-scanner.umd.min.js',
    })

    // QRコードページへ移動
    await page.getByRole('link', { name: 'QRコード' }).click()
    await page.waitForURL('/qr')

    // 画像要素を取得
    await page.waitForTimeout(1000)
    const qrCodeImg = page.getByRole('img', { name: 'QRコード' })
    const qrCodeSrc = await qrCodeImg?.getAttribute('src')

    // 画像のスキャン
    const qrCodeUrl = await page.evaluate(async (imgSrc) => {
        return window.QrScanner.scanImage(imgSrc)
    }, qrCodeSrc)

    expect(qrCodeUrl).toBe('http://localhost:8080/payment?hoge=fuga')

    // 決済画面に移動
    await page.goto(qrCodeUrl)

    ...});

E2Eテストの実行環境

CI に組み込むため実行環境には GitHub Actions を採用し、Docker Compose を使用してテスト対象のアプリケーションを起動しています。
これにより、以下のような利点を得ることができました。

  • アプリケーションの構築が自動化され、常に同じ状態でテストを実行可能
  • コンテナ環境を使用することで、本番に近い環境でのテストが可能
  • Docker Network 機能により、テストコンテナからアプリケーションコンテナやDBコンテナへのアクセスが容易

以下は、実際の GitHub Actions のワークフローの設定例です。
こちらも省略改変していますが、以下のようなイメージです。

name: E2E Tests
on:
  push:
    branches: [ develop ]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build and Start Application
        # アプリケーションのビルドと起動を行う
      - name: Setup npm
        uses: ./.github/actions/setup-npm
      - name: Install Playwright
        run: npx playwright install --with-deps
      - name: Run Playwright
        run: npx wait-on tcp:8080 && npm run test:e2e

実運用から得られた成果

プロジェクトでの実際の運用を通じて、以下のような具体的な成果を得ることができました。

  • CI への組み込みによる自動検証の実現
  • コードレビュー時の動作確認の効率化
  • テストコードを通じた仕様の共有

動作確認の効率化という点では特に得られた成果は大きいと考えています。プルリクエストのマージや、dependabot によるライブラリのアップデートの検証のたびに手動で確認を行うのは骨が折れますが、テスト自動化により開発者の作業負担を大幅に軽減することができました。

おわりに

今後は Playwright の fixture を活用した Page Object Model パターンの導入などにもチャレンジしていきたいと考えています。その過程で得られた知見についても、またどこかで共有できればと思います。

最後までお読みいただきありがとうございました。


※「QRコード」は株式会社デンソーウェーブの登録商標です。

BABY JOB  テックブログ

Discussion