RemitAid Tech Blog
🚗

RemitAidが取り組むフロントエンドのE2Eテスト —— Playwright MCP + AI Agentによる自動化までの道のり

に公開

こんにちは!RemitAid CTOの@iTakacです。
今回はPlaywrightやMCP、AI Agentを活用したテスト自動化までの道のりについて、具体的な実践方法を交えながらご紹介いたします。

フロントエンドのテストが欲しい

現在弊社のフロントエンドアプリケーションにはテストコードがありません。
B2B向けの管理画面を提供する中で、複雑なUXはないとはいえテストがないことで大規模なリファクタリングに二の足を踏んでしまうことが多々あります。
直近では金額を取り扱う変数が浮動小数点だったため、UIでの表示に不具合がリリース前のQAで発覚しました。
この事象自体は単なる一つのバグに過ぎませんが、潜在的には金融領域でソフトウェアを提供している以上、金額を取り扱う変数や型はdecimal型で定義するのが理想であるとの思想のもと、フロントエンドに関わる全ての金額の変数を見直すことになりました。
まさにそのときにも、全体に影響を及ぼすソフトウェアの変更になるので、仕様が劣後したり不具合が発生していないことを保証する仕組み、つまりテストコードの重要性を痛感しました。

同時に今年に入ってからのMCPサーバーの話題もあり、AI Agentとの親和性をうまく活用すればプログラムを書かずとも自然言語を使っていい感じにテスト環境の構築ができるのではないかという仮説が立ちました。

MCP + AI Agentで変わる開発者体験

テストを実行するのはAI Agentではなくテストコードにする

検討初期では完全自然言語でテストシナリオを書き、AI Agentに自律的に動作してもらうことを期待しましたが、それは辞めました。
自然言語を解釈し、AgentがTool Useする能力は年々高まっているとはいえ、まだ実用的と言えるアウトプットにはならなかったからです。
具体的には、一覧画面の項目の過不足の検証はできても、右上にあるCreateボタンを押下した先の処理を実行してくれませんでした。
なによりも何のテストをしてくれたのか、テスト結果はどうだったのか、網羅的にやってくれたのかが完全にブラックボックスで、不安が拭いきれませんでした。
(この辺りは、しっかりテスト結果をレポートするプロンプトの工夫で回避できたかもしれませんが...)

総論として人間と同じ精度でのテスト検証にはまだ隔たりを感じます。

テストコードはAI Agentで自動生成する

一方で60~80点くらいのアウトプットを最速で出すにはLLMが最適です。
従ってテストコードを60~80点で仕上げてもらい、残りの点数を人間が埋めるという役割分担で、仕組みを構築しました。
具体的には

  1. Playwright MCPサーバーをインストールします。
# Claude Codeで実行
claude mcp add playwright npx @playwright/mcp@latest
  1. Playwrightをインストールします。
npx playwright install
  1. カスタムスラッシュコマンドを用意します。
    普段の開発ではClaude Codeを使っており、カスタムスラッシュコマンドを用意することでなるべく日常に溶け込むことを意識しました。
    具体的には/pw_record 〇〇画面のように入力することでテストコードを自動生成します。
    カスタムスラッシュコマンドのプロンプトの一部がこちらです。
---
  allowed-tools: Bash(git:*), Bash(npm:*), Read(*.md), Fetch(*)
  description: "引数で指定した機能をテストしてplaywrightのテストコードを作成します。例)/pw_record 
  両替一覧"
---

## 目的
引数で指定した機能をテストしてplaywrightのテストコードを作成します。
作成されたテストコードは`npx playwright test ***.ts`により実行可能な状態にしてください。
## 既存テストコードとの差分管理

### 基本方針
すでにテストコードが存在する場合は、**既存のテストを分析し、不足しているテストケースのみを追加**してください。
既存のテストを壊さず、重複を避け、カバレッジを向上させることを目的とします。

### ステップバイステップの差分分析手順

#### 1. 既存テストファイルの検索と読み取り
\```bash
# 対象機能名でテストファイルを検索
Glob ツールで **/*{機能名}*.spec.ts を検索
Read ツールで該当するテストファイルを全て読み取る
\```

#### 2. 既存テストのカバレッジ分析
以下の観点で、既存テストが**何をカバーしているか**を明確にリスト化する:
- ✅ カバー済み:正常系の基本操作
- ✅ カバー済み:必須項目のバリデーション
- ❌ 未カバー:小数点を含む数値入力
- ❌ 未カバー:境界値テスト(最大文字数超過)
- ❌ 未カバー:通貨切り替え機能
- etc...

**重要:TodoWrite ツールで「カバー済み」と「未カバー」を明確にリストアップすること**

#### 3. 新規チェックリストとの照合
本プロンプトの「テストの内容」セクションのチェックリストと照合し、以下を判断:
- **追加が必要なテストケース**:既存にない項目
- **改善が必要なテストケース**:既存にあるが不十分な項目(例:整数のみで小数点をテストしていない)
- **十分なテストケース**:既に網羅的にカバーされている項目

一部抜粋ではありますがこのようなプロンプトを用意することで60~80点のテストコードを出力するには十分でした。

Github Actionsを使ってCI/CDのパイプライン上で実行

せっかく作ったテストコードも常に回しておかないと意味がないので、CI/CDのパイプラインに組み込みました。
具体的にはdevelopブランチにマージされたタイミングでnpx playwright testを実行するシンプルなGithub Actionsを用意しました。


name: Playwright Tests

on:
  push:
    branches:
      - develop
  workflow_dispatch:

jobs:
  test:
    runs-on: ubuntu-latest
    timeout-minutes: 30

    steps:
      - name: Checkout code
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

      - name: Setup Node.js
        uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
        with:
          node-version: '22.12.0'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Install Playwright browsers
        run: npx playwright install --with-deps chromium

    # FIXME:Amplifyのデプロイ待機時間をハードコーディング(将来的にはポーリングスクリプトなどを実装)
      - name: Wait for Amplify deployment
        run: |
          echo "Waiting for Amplify deployment to complete..."
          sleep 240

      - name: Run Playwright tests
        run: npx playwright test
        env:
          PLAYWRIGHT_TEST_EMAIL: ${{ secrets.PLAYWRIGHT_TEST_EMAIL }}
          PLAYWRIGHT_TEST_PASSWORD: ${{ secrets.PLAYWRIGHT_TEST_PASSWORD }}
          PLAYWRIGHT_BASE_URL: ${{ secrets.PLAYWRIGHT_BASE_URL }}

      - name: Upload Playwright report
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        if: ${{ !cancelled() && !env.ACT }}
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 30

体験はこうなった

新しい機能開発を実装後に、/pw_recordコマンドでテストコードを自動生成し、生成したテストコードとプロダクションコードをコミットするだけです。

ただ前述の通り、LLMが生成するテストコードをノールックでpushできるほどの精度ではないため、開発者が要件を満たしているか、仕様を網羅しているかなどなどは確認する必要があります。
それでもゼロからテストコードを生成することと、スタートが60~80点の出来を修正することを比べると後者の方が圧倒的に楽なことは言うまでもありません。

学びと今後の課題

今回の仕組みでもまだ弊社環境特有の問題に起因する課題は残っています。
弊社ではAWS Amplifyにフロントエンドアプリをデプロイしており、Github連携をパイプラインとしています。
従って新機能をテストするにはマージ後になってしまいます。
プレビュー環境などでテストすることも検討しましたが、連携しているAPIサーバーのCORSなどの関係で動的にURLが変更するプレビュー環境との設定をセキュリティを保ちながら整備するのは犬の道[1]すぎて諦めました。

一方でこの仕組み自体の可能性を感じた点があります。
弊社ではお客さまが操作する管理画面の操作方法を説明するご利用ガイドを用意しています。
新しい機能を開発すると必ず発生するご利用ガイドのメンテナンスについても、今回の仕組みを応用することで自動化できる可能性を感じたのが今回の学びでした。

今回はPlaywright MCPとAI Agentを組み合わせて整備したテスト環境を紹介させていただきました。
それでは次回の投稿をお楽しみに〜!

告知

Podcast 「RemiTalk」では普段の会社の様子を赤裸々に語っています。
もし良ければ聴いてみてください!
https://podcasts.apple.com/jp/podcast/remitalk/id1826516525
Podcast 文字起こしはこちら
https://note.com/remitaid

脚注
  1. https://rehaon.com/contents/reading-cafe-2023-11/ ↩︎

RemitAid Tech Blog
RemitAid Tech Blog

Discussion