はじめに
メディフォン株式会社でバックエンドエンジニアをしている澤部です。
私たちが提供しているクラウド型健康管理システム「mediment(メディメント)」は、産業保健の複雑な業務フローを支えるプロダクトです。その品質向上とエンジニアの検証工数削減を目的として、この度E2E(End-to-End)テスト基盤を刷新しました。
今回は、Playwrightの選定理由から、AI(Claude Code)を活用した実装の効率化、インフラ側の落とし穴など、一連の取り組みをご紹介します。
なぜPlaywrightを選んだのか?
E2Eテストフレームワークの選定にあたっては、CypressとPlaywrightが有力な候補となります。当社でも一部のフロントエンドテストにCypressを利用していましたが、本格的なE2Eテスト導入にあたり、最終的にPlaywrightを採用しました。
選定の決め手:
今後テスト数が増大することを見据え、マルチスレッドによる高速な実行環境が不可欠だと判断しました。また、標準搭載のcodegen(ブラウザ操作の自動コード化)が非常に強力で、実装コストを大幅に下げられる点が魅力でした。
Page Object Model (POM)とAIによる実装の自動化
1.POMによるメンテナンス性の向上
E2Eテストの最大の敵は、画面の仕様変更によってテストが失敗する「テストの脆さ」です。これを防ぐため、Page Object Model (POM)を徹底しています。
POMとは?
「UI要素の定義・操作」と「テストシナリオ(ロジック)」を分離する設計手法です。例えばログインボタンのIDが変わった場合でも、修正するのはLoginPageクラスの1箇所だけで済み、各テストファイルを書き換える必要がありません。
2.Claude Codeによる「POM生成の自動化」
POMは保守性に優れますが、クラス定義を手動で作るのは手間がかかります。そこで、AI(Claude Code)のカスタムスキルを作成し、以下のフローを構築しました。
- 録画:playwright codegenでブラウザ操作を記録。
- 変換:生成された生のコードをAIが解析。
- マッピング:プロジェクトのPOMパターンに合わせ、既存クラスへの追記やメソッド化をAIが代行。
この「人間が操作し、AIが設計パターンに落とし込む」ワークフローにより、実装スピードが飛躍的に向上しました。
テスト実行環境:なぜ「ステージング」を選んだのか
一般的にE2Eは「CIランナー(Docker等)上のクローズド環境」か「ステージング等の実環境」で実行されます。私たちは後者のステージング環境実行方式を採用しました。
- 環境の再現性:
medimentは本番に近いインフラ構成をステージングで再現しています。実際のネットワークやミドルウェアを通すことで、より本番に近い状態での品質担保が可能になります。 - 外部サービス連携の拡張性:
将来的にサードパーティAPIと連携する際、モック(擬似プログラム)の保守コストを抑えつつ、精度の高い疎通確認が行える利点があります。
セキュリティ:IAP保護環境への「キーレス認証」
ステージング環境はIAP(Identity-Aware Proxy)で保護されています。GitHub Actionsからセキュアにアクセスするため、Workload Identity Federationを活用した「キーレス認証」を組み込みました。
- OIDC連携:GitHub ActionsからGCPの一時的な権限を取得(サービスアカウントキーは不要)。
- トークン生成:IAPクライアントIDを対象(Audience)としたIDトークンを動的に生成。
- ヘッダー付与:PlaywrightのextraHTTPHeadersにAuthorization:Bearer<IDトークン>を自動付与。
これにより、認証情報をハードコードすることなく、安全にテストを実行できる環境を構築しました。
E2Eリポジトリ連動:PATを利用しない「GitHub App認証」
デプロイが完了した直後に、別リポジトリで管理しているPlaywrightのE2Eテストを自動でキックする仕組み(リポジトリ間連携)も構築しました。
ここでも、開発者個人の「Personal Access Token (PAT)」は一切使用していません。代わりに、組織(Organization)に紐づくGitHub Appを作成し、その権限を利用するアプローチを採用しています。
- 属人性の排除:個人のPATに依存すると、作成者の退職や異動によって突然CI/CDパイプラインが崩壊するリスク(属人性)が生じます。GitHub Appを利用することで、メンバーの入れ替わりに影響されない強固な運用を実現しました。
- 最小権限の原則:個人のアカウントが持つ広範な権限とは異なり、GitHub Appであれば「E2EテストリポジトリのActionsを手動実行(workflow_dispatch)する権限のみ」といったように、必要最小限のアクセス権だけをピンポイントで付与できます。
- 使い捨てトークンの動的生成:GitHub Actionsの実行時に、Appの秘密鍵を用いて「有効期限が短い使い捨てアクセストークン」を動的に発行しています。これにより、認証情報の漏洩リスクを低減しています。
GCPへのWorkload Identity Federationによる「キーレス認証」と同様に、GitHub内部の連携においても徹底して「永続的な強い鍵を持たせない」セキュアな設計を心がけました。
運用で直面した壁:Cloud Armorのレート制限
CI導入後、テストが断続的に403Forbiddenで失敗する事象が発生しました。
原因はWAFであるCloud Armorのレート制限でした。Playwrightのマルチプロセスによる超高速な並列実行が、通常のユーザー利用を想定したしきい値を一瞬で超えてしまい、不審な一斉アクセス(DoS攻撃など)と判定されていました。
安全にテストを実行させるために以下の対策を行いました。
- Playwright側:playwright.config.tsのworkers設定を調整し、CI実行時の最大並列数をCloud Armorが許容できる現実的なリクエスト密度に制限。
- Cloud Armor側:検証環境に限り、E2Eテストのバースト的なトラフィックを検知・遮断しないよう、制限のしきい値をテストの並列数に見合った最適な値へと微調整。
アプリケーションのコード(並列数)だけでなく、インフラ側の防御設定との整合性を考慮して双方をチューニングする必要があるという、E2Eならではの良い学びになりました。
まとめ
Playwrightへの移行と周辺インフラの整備により、medimentの開発サイクルはより堅牢になりました。「本番に近い環境」でテストを回す安心感は、リリース速度の向上にも寄与しています。
今後はテストカバレッジを拡大し、さらに「壊れにくい」テストを目指して改善を続けていきます。
メディフォンでは、技術で医療現場を支える仲間を募集しています!
興味を持っていただけた方は、ぜひカジュアルにお話ししましょう。
メディフォンでは、一緒に働くメンバーを募集しています。
「すべての多様な人々が自分の意思で、できるだけ長くいきいきと活躍する社会」をつくるというビジョンに共感し、一緒に挑戦していただける方との出会いを、お待ちしています!
詳細は、ぜひ採用サイトをご覧ください。
https://mediphone.co.jp/recruit/