【E2Eテスト自動化】Playwright×pytestで実現するAIお絵かきバトルの多言語・UI・AI生成フロー自動検証
1. はじめに:個人開発ゲームこそ「自動E2Eテスト」が必要な理由
「Doodle Fighter」のように、HTML5 Canvasでのリアルタイム描画、FastAPIバックエンドとの通信、Gemini Vision APIによるAI解析、そしてSupabaseを通じた非同期マッチングを行うWebゲームでは、「機能拡張時のデグレ(退行バグ)」が個人開発者にとって最大のトラウマになります。
特に前回の記事で紹介した「多言語対応(i18n)」や「PWA対応」を導入すると、単にボタンをクリックするだけでなく、「ロケールを切り替えた瞬間にDOMテキストが正確に翻訳されているか」「未作成状態の空表示が崩れていないか」といった検証要件が掛け算式に増大します。
これらを毎リリース手動でクリックして確認するのは不可能です。そこで私たちは、高速かつブラウザコンテキストの独立性に優れた Playwright (Python版: pytest-playwright) を採用し、実際のユーザー操作とAIキャラクター診断フローを一気通貫でテストするE2E(End-to-End)自動テスト基盤を構築しました。
2. なぜPlaywright×pytestを採用したのか?
数あるE2Eテストフレームワーク(Selenium, Cypress, Puppeteerなど)の中でPlaywrightを採用した最大の理由は以下の3点です:
- 驚異的な動作速度とオートリトライ機能: DOM要素の描画アニメーションや非同期フェッチ完了を自動で待機(Auto-waiting)してくれるため、
sleep()を多用する脆いテスト(Flaky tests)から脱却できます。 - マウスイベント・Touch APIのシミュレーション: ゲームの核となる「Canvasへの線画描画(ドラッグ操作)」を、プログラムからミリ秒単位で正確に再現可能です。
- 既存バックエンド(FastAPI / Python)との高い親和性:
pytest-playwrightを使用することで、pytestのフィクスチャ機能やPythonのエコシステムをそのままテストコードに流用できます。
3. 自己完結型 AAA パターンによるAIキャラクター生成フロー自動化
AIお絵かきゲームにおける最大の難関は、「事前に静的なテストデータ(キャラクターカード)を用意するだけでは、実際のAI診断フローを検証できない」という点です。
そこで私たちは、テスト関数自身が「キャンバスに絵を描き → AI評価を受け → 生成結果詳細モーダルが開く」までを1つのシナリオとして完結させる 自己完結型 AAA(Arrange-Act-Assert)パターン を実装しました。
// tests/e2e/test_02_multilingual.py より抜粋
def test_m18n_04_self_contained_char_creation_and_modal(page: Page):
"""
自己完結型 AAA パターンによるキャラクター生成&詳細モーダル検証
"""
page.goto("http://127.0.0.1:8000/play.html")
page.wait_for_timeout(1000)
# 1. 英語モードへの切り替え
page.click("#profileBtn")
page.wait_for_selector("#profileModal", state="visible")
page.select_option("#language-select", "en")
page.click("#closeProfileBtn")
# 2. Arrange: キャンバス中央にマウス操作で線を自動描画
canvas = page.locator("#drawCanvas")
box = canvas.bounding_box()
assert box is not None
center_x = box["x"] + box["width"] / 2
center_y = box["y"] + box["height"] / 2
page.mouse.move(center_x - 50, center_y - 50)
page.mouse.down() # マウスボタン押し下げ(描画開始)
page.mouse.move(center_x + 50, center_y + 50, steps=10) # 10ステップで滑らかに線を描く
page.mouse.up() # マウスボタン解放(描画終了)
# 3. Act & Assert: キャラクター生成と英語モーダルのテキスト検証
# (以降、生成ボタンクリックとAI講評・必殺技ラベルの英語表示アサーション)
このテストのポイントは、page.mouse.move(..., steps=10) のように steps パラメータを指定して滑らかに座標を移動させる点です。これにより、アンチチートロジック(描画時間やストローク数検知)に誤検知されることなく、本物の人間が描いたような線画入力フェーズを自動再現できます。
4. 多言語UI即時反映と「空状態(0件状態)」の厳格な検証
多言語化(i18n)テストで落とし穴になりやすいのが、「データが存在しない初期状態(空状態)の翻訳メッセージ」がハードコードされたまま放置される問題です。
以前のテストコードでは「キャラクターが1件もなければテストをスキップする」という甘い運用をしていましたが、今回のE2Eリファクタリングにて、「あえて未作成状態の画面を開き、0件状態のメッセージそのものが英語に切り替わっているかを厳格に肯定検証する」よう規律を改めました。
def test_m18n_03_empty_state_messages(page: Page):
"""
空状態(0件状態)の動的メッセージ多言語化検証
"""
page.goto("http://127.0.0.1:8000/play.html")
# 言語セレクターを 'en' に変更
page.click("#profileBtn")
page.wait_for_selector("#profileModal", state="visible")
page.select_option("#language-select", "en")
# 1. マイキャラクター一覧の空メッセージが英語であること
expect(page.locator("#myCharactersList")).to_contain_text("No characters yet. Create one from the Draw tab!")
page.click("#closeProfileBtn")
# 2. バトル画面での戦闘キャラクター未選択・0件警告の英語検証
page.click("button[data-target='battle']")
expect(page.locator("#myBattleCharacterSelect")).to_contain_text("You have no characters... Create one from Draw!")
expect(page.locator("#startRandomBattleBtn")).to_have_text("🔥 Start Random Match!")
Playwrightの expect(locator).to_contain_text(...) は、非同期に翻訳辞書(JSON)がロードされてDOMが書き換わるまでの間、自動的にリトライを繰り返します。これにより、Vanilla JSでの動的レンダリングとテストエンジンの間の競合状態(Race condition)を完全に排除できました。
5. モーダルやアニメーションUIをテストする際の実践Tips
SPAやゲームUIで頻繁に用いられるモーダルダイアログ(Tailwind CSSの transition や opacity-0 pointer-events-none などで制御される要素)をテストする際、単にクリック指令を出すと「まだモーダルが開ききっておらずクリックを空振りする」エラーが発生しがちです。
私たちは以下の2ルールを徹底することで、テスト実行の成功率100%を達成しました:
- 状態の明示的待機: モーダルを開く/閉じるアクションの直後には必ず
page.wait_for_selector("#profileModal", state="visible")またはstate="hidden"を挟む。 .firstlocatorの活用: ナビゲーションバーとドロワーメニューなどで同一のdata-i18n="start_game"属性を持つ要素が複数存在する場合、page.locator("...").firstを明示的に指定して曖昧性(Strict mode violation)を回避する。
6. まとめ:安心感が最高の開発スピードを生む
Playwrightとpytestを導入し、「マウスでの線画描画」「AI生成」「多言語切り替え」「空状態検証」といった重要ユースケースをすべてCI/ローカルで自動実行できるようにした結果、「どれだけ大きなコードリファクタリングを行っても、コマンド一発でバグがないことを確信できる」という圧倒的な心理的安心感が得られました。
個人開発や少人数チームこそ、手動テストにかける膨大な時間を削減し、クリエイティブな機能開発にリソースを集中させるために、PlaywrightによるE2Eテスト自動化を強くおすすめします!