🧑‍🎄

Playwright Test generatorを利用したE2Eテスト ことはじめ

2023/12/03に公開

このエントリーは3-shake Advent Calendar 2023 3日目の記事です。
株式会社スリーシェイクのメンバーが各々自由に技術・非技術ネタを投稿するカレンダーとなります。

はじめに

現在、私はマイクロサービスを運用するSREを支援する人として活動しています。

運用チームやSREが主導となって実施するメンテナンスやアップデート作業などでは、アップデート後の動作確認として、ブラウザを介したWebアプリケーションの簡易目視確認をします。

これらの確認項目は、手順書へ項目を記載し、必要に応じてエビデンスをスクリーンショットで取得する必要があります。確認作業を網羅的にしようとすればするほど、手順書への記載内容が増え、オペレーションが増え、トイルになると感じています。

今回は、Playwrightの機能であるPlaywright Test generatorを利用し、自動で、網羅的に、簡単に、E2Eテストのコードを書いてみようというのが主旨となります。

対象読者

  • Playwrightが気になっている方、簡単に始めてみたい方、とりあえずやってみたい方
  • 誰がE2Eテストをするのか明確でない組織に属している方
  • QA担当者が不在な組織に属している方
  • WebアプリケーションのE2Eテストができていないことに課題を感じている方
  • マイクロサービスを運用している運用チームやSREの方
  • Webアプリケーションのアップデート作業後に、網羅的に目視動作確認するのがトイルだと感じている方

紹介すること

Playwrightの機能である、Playwright Test generator(テスト自動生成機能)を利用して、ブラウザを介したWebアプリケーションのE2Eテストを簡単に実装する方法を紹介します。
今回は、株式会社スリーシェイクのホームページを利用して、E2Eテストを実施します。

Playwrightとは

Playwrightとは、Webアプリケーション向けのE2Eテストの自動化フレームワークです。
特徴としては、下記があります。詳細は公式サイトをご確認ください。

  • 特徴
    • クロスブラウザ対応
      • Chromium、WebKit、Firefoxなど、最新のレンダリングエンジンをすべてサポート
    • クロスプラットフォーム
      • Windows、Linux、macOS、ローカル、CI、ヘッドレス、ヘッドレスでテストが可能
    • 多言語対応
      • TypeScript、JavaScript、Python、.NET、Java で Playwright API を使用可能
    • モバイルウェブテスト
      • Google Chrome for AndroidとMobile Safariのネイティブ・モバイル・エミュレーションを提供 同じレンダリングエンジンがデスクトップでもクラウドでも動作する
  • 公式サイト
  • ソースコード

Playwright Test generatorを利用したWebアプリケーションのE2Eテスト

Playwright Test generatorとは

ブラウザアクションに基づいて、テストを自動で生成するPlaywrightの機能です。

テスト内容

株式会社スリーシェイクのホームページを利用して、Playwright Test generatorを利用したE2Eテストコードの自動生成およびE2Eテストを実行します。

確認すること

項目 エンドポイント 確認すること
1 https://3-shake.com/ 表示が正常か、ヘッダー 「About Us」から正常にページ遷移できるか
2 https://3-shake.com/about/ 表示が正常か、ヘッダー 「Services」から正常にページ遷移できるか
3 https://3-shake.com/#sec-services 表示が正常か、ヘッダー 「News」から正常にページ遷移できるか
4 https://3-shake.com/category/news/ 表示が正常か、ヘッダー 「Recruit」から正常にリダイレクトされるか
5 https://jobs-3-shake.com/ 表示が正常か

E2Eテスト シナリオ

ヘッダーの項目を順番に移動し、それぞれのページにてスクリーンショットを取得するシナリオを実行します。

  1. 株式会社スリーシェイク のTopページを表示
  2. スクリーンショットを取得し、画像を保存
  3. About Usページに移動
  4. スクリーンショットを取得し、画像を保存
  5. Servicesページ に移動
  6. スクリーンショットを取得し、画像を保存
  7. Newsページに移動
  8. スクリーンショットを取得し、画像を保存
  9. Recruitページに移動
  10. スクリーンショットを取得し、画像を保存

事前準備

動作環境

  • M2 macOS : Ventura 13.6.1
  • python : 3.11.6
  • pip : 23.3.1
  • Playwright : 1.40.0

playwrightのインストール

  1. Pytest pluginのインストール

    pip install pytest-playwright
    
  2. Playwrightのインストール

    playwright install
    

シナリオの自動生成を実行 (Test generator)

  1. 下記コマンドを実行する

    playwright codegen https://3-shake.com/
    
  2. ChromiumとPlaywright Inspectorが立ち上がることを確認する

    • Chromiumでシナリオに基づいたブラウザ操作をする
      playwright01.png
  3. Playwright Inspectorの自動生成されたコードをコピーしてコード化する

    playwright-test.py
    from playwright.sync_api import Playwright, sync_playwright, expect
    
    def run(playwright: Playwright) -> None:
        browser = playwright.chromium.launch(headless=False)
        context = browser.new_context()
        page = context.new_page()
        page.goto("https://3-shake.com/")
        page.get_by_role("banner").get_by_role("link", name="About Us").click()
        page.get_by_role("banner").get_by_role("link", name="Services").click()
        page.get_by_role("banner").get_by_role("link", name="News").click()
        page.get_by_role("banner").get_by_role("link", name="Recruit").click()
    
        # ---------------------
        context.close()
        browser.close()
    
    with sync_playwright() as playwright:
        run(playwright)
    
  4. 一部コードを修正する

    • 5秒のwaitと各々のページでスクリーンショットを取得する処理を追加

      playwright-test2.py
      from playwright.sync_api import Playwright, sync_playwright, expect
      from datetime import datetime
      
      def run(playwright: Playwright) -> None:
          browser = playwright.chromium.launch(headless=False)
          context = browser.new_context()
          page = context.new_page()
      
      		# 1. Topページ表示
          page.goto("https://3-shake.com/")
          page.wait_for_timeout(5000)
          current_datetime = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
          screenshot_filename = f"screenshot_top_{current_datetime}.png"
          page.screenshot(path=screenshot_filename)
          page.wait_for_timeout(5000)
      
      		# 2. About Usページ表示
          page.get_by_role("banner").get_by_role("link", name="About Us").click()
          page.wait_for_timeout(5000)
          current_datetime = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
          screenshot_filename = f"screenshot_about_{current_datetime}.png"
          page.screenshot(path=screenshot_filename)
          page.wait_for_timeout(5000)
      
      		# 3. Servicesページ表示
          page.get_by_role("banner").get_by_role("link", name="Services").click()
          page.wait_for_timeout(5000)
          current_datetime = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
          screenshot_filename = f"screenshot_sec-services_{current_datetime}.png"
          page.screenshot(path=screenshot_filename)
          page.wait_for_timeout(5000)
      
      		# 4. Newsページ表示
          page.get_by_role("banner").get_by_role("link", name="News").click()
          page.wait_for_timeout(5000)
          current_datetime = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
          screenshot_filename = f"screenshot_news_{current_datetime}.png"
          page.screenshot(path=screenshot_filename)
          page.wait_for_timeout(5000)
      
      		# 5. Recruitページ表示
          page.get_by_role("banner").get_by_role("link", name="Recruit").click()
          page.wait_for_timeout(5000)
          current_datetime = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
          screenshot_filename = f"screenshot_recruit_{current_datetime}.png"
          page.screenshot(path=screenshot_filename)
          page.wait_for_timeout(5000)
      
          # ---------------------
          context.close()
          browser.close()
      
      with sync_playwright() as playwright:
          run(playwright)
      
  5. 再実行をしてみる

    python playwright-test2.py
    
  6. 動作確認

    • スクリーンショットが正常に取得できたことを確認する
    • Topページ
      playwright-top.png
    • About Usページ
      playwright-about-us.png
    • Servicesページ
      playwright-sec-services.png
    • Newsページ
    • Recruitページ

まとめ

Playwrightの機能である、Playwright Test generator(テスト自動生成機能)を紹介させていただきました。見ていただいたようにとても容易にE2Eのテストコードを作成することができました。

マイクロサービスを運用している場合、複数サービスが存在し、スクラムチームがまたがっているケースが多く、全体にまたがったQAチームが存在しない組織構成となっている場合があるかと思います。そのような組織構成の場合、誰がE2Eテストを実施するのか明確でないなどの課題があります。

この課題を解決するには、誰かが担当を持つ必要がありますが、組織を比較的マクロに見れているであろう、運用チームやSREの方が担当となり、気軽に、簡単にE2Eテストが実施できれば良いなと考えています。(※組織の構成次第で担当を持つべき人は変わるとは思います)

また、一般的にE2Eテストは壊れやすく定期的なメンテナンスが必要で、メンテナンスコストが高いことが課題としてありますが、本記事で紹介した機能は、実装が比較的容易なため、E2Eテストコードのリファクタリングが楽であるというメリットがあると思います。

ぜひ、利用してみてください。

Playwright Test generatorについて、今回はPythonでの実行を紹介させていただきましたが、VS Codeの拡張機能などでも利用することができます。今回のサンプルコードは、Github:Playwright-test にもありますので気になった方はご確認ください。

参考

Discussion