🤖

WebのE2Eテスト自動化〜テストレポート編〜

2024/04/10に公開

こんにちは!株式会社ココナラのプロダクト開発部QAチーム所属の"まる"こと鈴木です。
今回は以前投稿した、「WebのE2Eテスト自動化〜ツール選定編〜」の続編に当たります。
https://zenn.dev/coconala/articles/40849ff2533f84

「なぜツール選定の次がテストレポート編やねん」とツッコミが聞こえてきそうですが、昨年のテスト自動化カンファレンス2023に登壇した際に、しれっと紹介したテストレポートツールへの質問が多かったので、今回はそちらに少しでもお答えできればと思い、このテーマを選びました。

テストレポートツール"reportportal"

弊社では、WebのE2Eテストのレポートツールとしてreportportalを利用しています。
https://reportportal.io/

まず前提として、テストレポートの必要性について整理します。ドキュメントとしてはJSTQBのAdvancedLevelシラバス〜テスト自動化エンジニア〜の中にある「5.テスト自動化のレポートとメトリクス」に詳細が記載されています。長いので説明は割愛しますが、個人的にまとめると...

  1. この自動テストは本当に意味があるの???
  2. この自動テストは健全なの???

に回答するために必要だと思っています(自戒)。他にも実行したテスト結果の確認しやすさも大事ですが、今回は量的に割愛します。

以上を踏まえた上で、reportportalの導入を決めた理由は3つです。

  1. AppのE2Eテストのレポートツールとして導入済みで、そちらと合わせたかったから。
  2. reportportalに結果を送信するためのエージェントがPlaywright用に用意されていたから。
  3. 上記質問への回答を可視化できたから!

早速導入!

reportportalの構築は、技術戦略室&インフラ・SREチームの方に実施して貰いました。なので構築後から説明していきます。ちなみにスペックは以下です。

Current version:API Service: 5.7.2;Jobs Service: 5.7.2;Authorization Service: 5.7.0;Service UI: 5.7.2;

まずは playwright.config.tsにreporter情報を追加します。

const RPconfig = {
  apiKey: process.env.REPORT_PORTAL_API_KEY,
  endpoint: process.env.REPORT_PORTAL_ENDPOINT,
  project: process.env.REPORT_PORTAL_PROJECT,
  launch: process.env.REPORT_PORTAL_LAUNCH,
  debug: false,
  attributes: [`isScheduleExecution:${process.env.SCHEDULE_EXECUTION}`],
  description: "ココナラ本体のe2e-webテスト",
};

export default defineConfig({
  // 割愛
  reporter: process.env.CI
    ? [
        ["./helpers/reporter/reportPortal.ts", RPconfig],
        ["./helpers/reporter/slack.ts", RPconfig],
      ]
    : "list",
  // 割愛
});

ローカルでの実行結果は送信しないように分岐を入れてます。

そしたら別に切り出している reportPortal.tsにreporterとしてどう振る舞って欲しいかを実装します。

import RPReporter from "@reportportal/agent-js-playwright";

class ReportPortalReporter extends RPReporter {
  async onEnd(): Promise<void> {
    // Force finish unfinished suites in case of interruptions
    if (this.suites.size > 0) {
      this.suites.forEach((value, key) => {
        this.suites.set(key, {
          ...value,
          testCount: 0,
          descendants: [],
        });
      });
      this.finishSuites();
    }

    if (!this.config.launchId) {
      const { promise } = this.client.finishLaunch(this.launchId, {
        endTime: this.client.helpers.now(),
        ...(this.customLaunchStatus && { status: this.customLaunchStatus }),
      });
      const { link } = await promise;
      // slack.ts で使用する
      process.env.REPORT_PORTAL_LAUNCH_ID = link.replace(/^.*\//, "");
      this.addRequestToPromisesQueue(promise, "Failed to finish launch.");
    }

    this.isLaunchFinishSend = true;
    await Promise.all(this.promises);
    this.launchId = "";
  }
}

export default ReportPortalReporter;

「何やってるのかわからない」と思いますが、ここはplaywright用のエージェント処理を"ほぼ"そのままOverrideしています。異なる点は以下だけです。

      // slack.ts で使用する
      process.env.REPORT_PORTAL_LAUNCH_ID = link.replace(/^.*\//, "");

今回は説明しませんが、自動テストの結果をSlackにリアルタイムに通知するために入れてます。なのでreportportalに結果を送信したいだけであれば、特に何もしなくて大丈夫です!

これで準備完了!早速CI環境でテスト実行してみます!CI環境でテスト実行すると以下のように実行が一覧として表示されます。一覧だけでも十分な情報が手に入りますね。
テスト実行一覧

可視化するメトリクスを定義しよう!

さて、テスト実行結果を取得できたら次はそれをメトリクスとして可視化していきます。具体的なメトリクスを説明する前に前提を整理しておきます。

Fail(テスト失敗)の定義

弊社ではテストのFailを以下6種類に分類しています。

失敗原因 定義
Product Bug プロダクト起因のバグ
Automation Bug 自動テスト起因のバグ
Behind Bug 仕様変更に遅れを取ってしまった自動テスト起因のバグ
System Issue 環境構築不備などの環境要因の失敗
External System Issue 外部サービス起因の失敗
No Defect 直前のテストケースが失敗したことによるSkip
To Investigate 要調査

reportportalでは失敗原因をカスタマイズできます。ここも便利ですね!
失敗原因

リグレッションテストの種類の定義

次に弊社ではリグレッションテストの種類が2種類あります。

種類 定義
チケット系 軽微な修正用のリグレッションテスト。ケース数を間引くため実行時間が短い
プロジェクト系 新規機能開発用のリグレッションテスト。ケース数が多い反面、実行時間が長い

この2種類の判別はテスト実行時に、属性(attribues)を付与することで識別できるようにしています。
リグレッションタイプ

前提は以上です!

自動テストのメトリクス

長くなりましたが、弊社で可視化している自動テストのメトリクスは以下です!

メトリクス 定義 なぜ可視化する? 観点 目標値
リグレッション検知数 Product Bugの件数 E2Eテストの最大の目的だから。あと偉い人の心を掴みやすいから 自動テストの有効性
自動テストの実行件数 実行した自動テスト数 手動テストをどれだけ自動化できたか知りたいから。あと偉い人が好きな観点だから 同上
テスト信頼性 (テスト実行数 - Fail数) / (テスト実行数) 低いとテスト結果への信用度が低下し、リリース判断に使えないことを意味するから。 自動テストの健全性 95%以上
テスト実行時間(チケット系) テスト開始してから終了するまでの時間 長いと運用負荷が高いことを意味するから。 同上 15分以内
テスト実行時間(プロジェクト系) 同上 同上 同上 30分以内

メトリクスを可視化しよう!

まずお見せします!
dashboard

詳細を説明していきます!

Summary

summary
こちらでは以下メトリクスを可視化しています。

  1. リグレッション検知数
  2. 自動テストの実行件数
  3. テスト信頼性

なので「この自動テスト、意味あるの??」と偉い人に聞かれたら、ダッシュボードを見せながら「そうですね...少なくとも今まで61,051件のテスト実行を自動化したうえで、リグレッションを7件検知しているくらいの意味はありますかね...」と答えましょう(?)

テスト実行時間

テスト実行時間
こちらでは以下のメトリクスを可視化しています。

  1. テスト実行時間(チケット系)
  2. テスト実行時間(プロジェクト系)

見てすぐ違和感に気づくと思いますが、グラフの上半分くらいから実行時間が半分くらいになっています。これは2024年2月にテスト並列化をした影響になります。モニタリングしているときに「テストがFailすると目標値のテスト実行時間をクリアできないときがある」ことに気づいて、テコ入れした形です。 「モニタリングし、改善点を見つけ、行動し、効果を測定する」 という理想的な改善プロセスだったと思っています。

その他

他にも月別で上記を作成したり、Flakyテストの一覧や失敗傾向、テストケース単位の実行時間もついでに可視化しています。

reportportalでの可視化の仕方

超絶簡単です。今回は試しにSummaryを作ってみたいと思います!
まずは各メトリクスを表示するためのダッシュボードを作ります。
ダッシュボード作成

ダッシュボードができたらウィジェットを作成します。
ウィジェット作成

するとreportportalが提供しているウィジェットの一覧が出てきます。今回は Overall statisticsを選択します。(このバリエーションの豊富さもいい!)
ウィジェットタイプ

次にウィジェットの設定をする画面が出てきます。ここが腕の見せどころです。まずフィルターを作っていきます!
ウィジェット設定

モニタリング対象のテスト実行だけにフィルタリングします。先程紹介した属性を使ってフィルタリングしてあげます。
フィルター作成

あとは見やすいように表示内容を整えてあげます。サマリーを作りたいので、本当は全実行を対象にしたいのですが、reportportal側の上限が600回までなので、Itemsには600を入れてます。
ウィジェットの見た目設定

最後にウィジェットの名前を入れてあげます。
ウィジェットの名前

そしたら完成です!
ウィジェット完成

このように用途に合わせて様々なウィジェットを作成することができます!

最後に

簡単にですがレポートツールreportportalについて紹介しました!
ただ課題もあり、例えば以下が挙げられます。

  1. テスト信頼性の分子部分を本当は テスト実行数 - (Automation Bugの件数 + Behind Bugの件数)にしたいが、現状可視化できていない。
  2. テストケース単位のテスト信頼性を現状可視化できていない。

ここらへんは色々試行錯誤しながら改善できたらと思っています。

本記事がこれから自動テストを推進しようと考えている方の目に留まり、かつテストレポートツール選定の一助になれば幸いです!

また弊社ではQA問わずエンジニア募集中です!少しでも興味を持たれた方がいましたら、エンジニア採用ページをご覧ください。
https://coconala.co.jp/recruit/engineer/

Discussion