見出し画像

PlaywrightとLookerStuidoでテスト結果のダッシュボードを作成してみた 前編


はじめに


こんにちは!SHIFTの平岡です。
今回は「PlaywrightとLookerStuidoでテスト結果のダッシュボードを作成してみた」をテーマに、前後編でご紹介していきたいと思います。

Playwrightで標準出力されるテストレポートは、1つのテストの結果を振り返ることはできますが、一定期間の中での複数のテストから見える傾向などの分析がしづらいという課題があります。そこで、Playwrightのテストデータをスプレッドシートへ出力することで、不具合傾向や自動テストに関する分析ができるようにしたいと考えました。 この記事では、次の技術に触れています。

  • Playwright: 自動テストの結果を収集する部分

  • GoogleAPI: 収集したデータをGoogleAPIを使用してスプレッドシートへ書き込んでいる

  • LookerStuido: Googleが用意しているダッシュボード・レポート作成ツール(スプレッドシートと連携がしやすい)

以上の技術に触れながら、この記事では次のような構成になっています。前編ではPlaywrightでテストデータを取得してスプレッドシートへのAPI連携までを、後編ではスプレッドシートのデータをインプットとしてLookerStuidoでデータをグラフや表として可視化するところまでを紹介します。 今回は無償のツールで構築することが前提条件であったため、スプレッドシートやLookerStuidioを活用しております。

Playwrightでテストデータを収集する(TypeScript)


  1. custom-reporter.tsを作成し、実行されるテストの「テスト実行結果」「テストシナリオデータ」「テストシナリオごとのエラーデータ」の3つを収集する。

  2. 「APIを呼び出し収集したデータを書き込む」関数を用意します。

  3. custom-reporter.tsでテスト完了時に収集したデータを使いAPI連携する関数が発火するようにしておきます。

※つまずいた点

この次の節で説明している通り、「Reporter」classには6つのイベントトリガーが標準装備されています。当初onStepBeginとonStepEndで「テストステップデータ」「テストステップごとのエラーデータ」を取得しようと試みましたが、収集したデータ量が膨大であったためその使用を断念しました。最終的には、onTestBeginとonTestEndで「テストシナリオデータ」「テストシナリオごとのエラーデータ」を取得するようにしました。onBeginとonEndで「テスト実行結果」というテスト全体のサマリーデータを収集する形にしました。

テストデータの構造イメージ

custom-reporter.tsの例と解説


以下ではPlaywrightでテスト結果のデータをまとめて取得します。PlaywrightのReporterのイベントトリガーを用いて、テスト結果を収集してスプレッドシートにAPI連携し送信します。各イベントトリガーで取得するデータを記述しています。

// custom-reporter.ts

export class MyReporter implements Reporter {

  onBegin(config: FullConfig, suite: Suite): void {
    //  Summaryデータの取得
    //  テスト1回あたりの実行に関するデータ

      //  テスト実行IDの設定(テストレポートごとにユニーク)
      MyReporter.EXCUTEID = dateTimeSecWithPadding(new Date());
      //  テスト開始時間の設定
      const startTime = dateSeparatedBySlash(new Date()) + " " + timeHHmmss(new Date());
      MyReporter.data.summary_data.test_begin_time = startTime;
      //  使用しているOSの設定
      MyReporter.data.summary_data.os = config.projects[0].use.userAgent;
      //  自動テストの対象のテスト環境を設定
      MyReporter.data.summary_data.env = Env.instance.EL_DOMAIN.match(/^[^.]+/)?.[0];
      //  githubから対象のテストコードのバージョンを取得
      MyReporter.data.summary_data.test_code_version = execCommand("git rev-parse main");
      //  CircleCIへのリンクURLを取得
      MyReporter.data.summary_data.circle_build_url = process.env.CIRCLE_BUILD_URL;
  }

  onTestBegin(test: TestCase): void {
    //  Scenariosデータの取得
    //  テストシナリオ1本に関するデータ

      //  テスト実行IDの設定(テストレポートごとにユニーク)
      onescenarioData.excute_ID = MyReporter.EXCUTEID;
      //  テストシナリオ開始時間の設定
      onescenarioData.test_begin_time = startTime;
      //  テストシナリオのタイトルの設定
      onescenarioData.scenario_name = test.title;
  }

  async onTestEnd(test: TestCase, result: TestResult): Promise<void> {
    //  Scenariosデータの取得
    //  テストシナリオ1本に関するデータ
      //  テストシナリオ終了時間の設定
        onescenarioData.test_end_time = endTime;
      //  テストシナリオのリピート回数を設定
        onescenarioData.repeat_eachIndex = test.repeatEachIndex;
      //  テストシナリオの予測されるステータス
        onescenarioData.expected_status = test.expectedStatus;
      //  テストシナリオの実行結果
        onescenarioData.outcome = test.outcome();
      //  テストシナリオのステータス
        onescenarioData.status = result.status;

    
    //  Errorsデータの取得(エラーデータがある場合)
    //  テストシナリオごとにまとめてエラーデータを取得
      //  エラーメッセージの取得
      //  エラー発生箇所の取得
   
  }

  async onEnd(result: FullResult): Promise<void> {
    //  Summaryデータの取得
    //  テスト1回あたりの実行に関するデータ
      //  テスト終了時間の設定
      const endTime = dateSeparatedBySlash(new Date()) + " " + timeHHmmss(new Date());
      MyReporter.data.summary_data.test_end_time = endTime;
    //  Scenariosデータの取得
    //  テストシナリオ1本に関するデータ
      MyReporter.data.scenarios_array_data = MyReporter.scenariosArrayData;
    //  Errorsデータの取得
    //  テストシナリオごとにまとめてエラーデータを取得
      MyReporter.data.errors_array_data = MyReporter.errorsArrayData;
    //  テスト結果をAPIでスプレッドシートへ連携
    //  ここまでで蓄積したデータをAPIで投げる
      await appendValues(MyReporter.data);

  }
}

1. Reporterクラスに用意されている6つのイベントトリガー

  1. onBegin:

    • テストスイートの実行が始まる際に呼ばれ、テストの概要を初期化します。ここで、テスト結果を格納するためのデータ構造を準備します。

  2. onTestBegin:

    • 各テストが始まる際に呼ばれ、テスト名や開始時間などの情報を収集できます。

  3. onTestEnd:

    • 各テストが終了した際に呼ばれ、テストの結果(成功・失敗)やエラーメッセージを収集できます。

  4. onEnd:

    • テストスイートの実行が終了した際に呼ばれ、収集したデータをスプレッドシートに送信します。

  5. onStepBegin:

    • 各テストステップが始まる際に呼ばれ、ステップの開始情報を収集するために使用されます。

  6. onStepEnd:

    • 各テストステップが終了した際に呼ばれ、ステップの結果を収集するために使用されます。

2. データ取得の変更

onStepBeginとonStepEndでは、取りたいデータがうまく取得できなかったため、テストの開始と終了の情報はonTestBeginとonTestEndで取得するように変更しました。このアプローチにより、テストの結果やエラーメッセージを確実に収集できるようになり、スプレッドシートへのデータ書き込みがスムーズに行えるようになりました。

APIを使用してデータを格納


収集したデータをスプレッドシートの列に合わせて加工して、APIを使用してスプレッドシートへ書き込みます。

1. APIを書き込むためのトークンの取得

Google Sheets APIを使用するためには、OAuth 2.0を利用して認証トークンを取得する必要があります。これにより、APIへのアクセスが許可され、スプレッドシートにデータを書き込むことができます。トークンは、Google Cloud Consoleで設定したOAuth 2.0クライアントIDを使用して取得します。

2. Playwrightで収集したデータをスプレッドシートの形に合わせて調整する

収集したテスト結果データは、スプレッドシートに書き込むために特定の形式に整形する必要があります。クラスを定義し、テスト結果をスプレッドシートの列に合わせて調整すると可読性も高まりメンテナンスがしやすいです。

3. APIをaxiosで実行して、データを書き込む

整形したデータをGoogle Sheets APIを使用してスプレッドシートに書き込むために、axiosを利用します。POSTリクエストを送信してデータをスプレッドシートに追加します。

このようにして、収集したデータをスプレッドシートの列に合わせて加工し、APIを使用してスプレッドシートに書き込むことができます。

スプレッドシートへのデータ書き込みの注意点


リクエスト数の制限

通常、Google Sheets APIでは、1分あたりのリクエスト数は60リクエストに制限されています。ただし、これはプロジェクトの使用状況やGoogleのポリシーによって変わる可能性があります。

1日あたりのリクエスト数は、通常500,000リクエストに制限されています。これもプロジェクトの使用状況によって異なる場合があります。

データサイズの制限

Google Sheets APIでは、1回のリクエストで更新できるセルの数は最大10,000セルです。これを超える場合は、複数のリクエストに分けて送信する必要があります。 1回のリクエストで送信できるデータの合計サイズは、最大10MBです。これには、リクエストのヘッダーやボディが含まれます。 また、スプレッドシートは1ドキュメントあたりの上限は1,000万セルです。

まとめ


PlaywrightとAPI連携を使用してテスト結果をスプレッドシートに書き込むことで、テストデータを分析しやすくなります。カスタムレポーターを利用することでテストデータを操作することもできます。データを蓄積しておくことでテストの傾向を把握し、より効果的なテスト戦略を立てることが可能になります。ぜひ、みなさんもプロジェクトに取り入れてみてください。


執筆者プロフィール:平岡 拓人
SHIFTの平岡です。入社3年目になります。
新卒で独立系Sierに就職し主にWEBシステムの構築に携わり、要件定義から開発まで経験しました。システム開発以外には、サーバの構築やNW構築経験があります。 2021年11月よりSHIFTで勤務しております。
主にQA・スクラムに関する業務に従事しており チャットアプリの技術支援としてコードから画面遷移図などのドキュメントを作成したりテストコードの開発を行っています。
趣味:#バスケ#キャンプ#登山#グルメ

お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/

PHOTO:UnsplashJonathan Simcoe