🎭

メトリクス取得のためのPlaywrightのレポート機能の活用

2024/04/30に公開

はじめに

この記事は、Playwright のレポート機能を活用して、テスト実行結果からメトリクスを取得する方法を紹介する。

Playwright のレポート機能

Playwright のレポート機能には、カスタムレポーターがある。このレポーターは、ビルトインのレポーターの他に、独自に実装したレポーターを使用して、テスト結果をレポートとして出力することができる。

カスタムレポーターの実装

レポータークラスの実装

カスタムレポーターを実装するためには、Reporterクラスを拡張したクラスを定義する。

src/custom-reporter/index.ts
class CustomReporter implements Reporter {
    // implement custom reporter
}

export default CustomReporter;

このクラスでは、主に以下のメソッドを定義することで、テスト実行のメトリクスに必要な値をレポート出力することができる。

このレポーターを使用するためには、playwright.config.tsreporter オプションにカスタムレポーターを指定する。

playwright.config.ts
export default defineConfig({
  reporter: [
    [
      "./src/custom-reporter/index.ts"
    ],
  ]
})

レポーターのオプション定義

カスタムレポーターのクラスのコンストラクタの引数でオプションを定義することができる。
例えば、出力するレポートのファイル名の指定などで用いることができる。

src/custom-reporter/index.ts
class CustomReporter implements Reporter {
  constructor(options: {filename: string} = {}) {
    this.filename = options.filename ?? "report.json";
  }
}

オプションの指定は、playwright.config.ts で以下のように指定する。

playwright.config.ts
export default defineConfig({
  reporter: [
      // タプルの2番目の要素にオプションを指定する
    [
      "./src/custom-reporter/index.ts",
      {
        filename: "custom-report.json"
      }
    ],
  ]
})

テスト実行のメトリクス

よく利用すると思われるメトリクスを以下に示す。

onEnd メソッドで取得できるメトリクス

  • テスト実行開始時刻: FullResult.startTime: Date
  • テスト実行結果: FullResult.status: 'passed' | 'failed' | 'timedout' | 'interrupted'
  • テスト実行時間 (ミリ秒単位): FullResult.duration: number

onTestEnd メソッドで取得できるメトリクス

実装例

以下にJSONファイルに上記のメトリクスを出力する例を示す。

src/custom-reporter/index.ts
import {
  TestCase,
  TestResult,
  Reporter,
  FullResult,
} from "@playwright/test/reporter";

type ResultOfTestCase = {
  id: string;
  outcome:   "skipped" | "expected" | "unexpected" | "flaky";
  durationInMs: number;
}

type ResultOfTestSuite = {
  startedAt: number;
  durationInMs: number;
  status: "passed"|"failed"|"timedout""interrupted"|"unknown";
  results: ResultOfTestCase[],
}


class CustomReporter implements Reporter {
  results: ResultOfTestCase[] = [];
  private filename: string;
  constructor(options: {filename: string} = {}) {
    this.filename = options.filename ?? "report.json";
  }

  onTestEnd(testCase: TestCase, testResult: TestResult): void {
    const result: ResultOfTestCase = {
      id: testCase.id,
      outcome: testCase.outcome(),
      durationInMs: testResult.duration,
    };
    this.results.push(result);
  }

  onEnd(fullResult: FullResult) {
    const result: ResultOfTestSuite = {
      startedAt: fullResult.startTime.getTime(),
      durationInMs: fullResult.duration,
      status: fullResult.status,
      results: this.results,
    };
    fs.writeFileSync(
      this.filename,
      JSON.stringify(report, null, 2),
    );
  }
}

GitHubで編集を提案

Discussion