nove-b

nove-b/AngularプロジェクトでPlaywrightを導入しTypeScriptで自動E2Eテストを実行する

Created Sun, 19 Jan 2025 00:00:00 +0000 Modified Tue, 11 Feb 2025 16:37:11 +0000

E2E(イーツーイー)

英語の「End-to-End(エンドツーエンド)」の略で、「端から端まで」を意味する。 E2Eテストはユーザーの視点からアプリケーション全体の動作を確認し、機能の一貫性と信頼性を保証する手法すること。

E2Eテストの自動化

自動化するツールはいくつかあり、それぞれメリットデメリットがあるっぽい。 下記は[ブラウザ拡張のE2Eテストを検討してみた(Playwright、Puppeteer、Cypress)とChatGPTの情報を混ぜ合わせた、メリットデメリット表。

項目PlaywrightPuppeteerCypressSelenium
サポートブラウザChromium, Chrome, Edge, Firefox, Webkit (Safari)Chrome, FirefoxChrome, Edge, Firefox, ElectronChrome, Edge, Firefox, Safari, IE
テストツールの有無🟡 (Jest を使えば可能)🟡 (外部ライブラリが必要)
複数タブ / ウィンドウ🛑
Shadow DOM🟡 (aria または pierce セレクタを使えば可能)🟡 (限定的なサポート)
ブラウザ拡張🟡🟡 (一部サポート)
要素の特定🟡🟡
要素の自動待機🟡🛑 (手動で記述が必要)
スクリーンショット
動画🛑🛑
実行速度🟡 (ブラウザ依存でやや遅い)

これだけ見るとPlaywrightが有望な気がする。 気になるのは要素の特定なので調べてみた結果、PuppeteerCypressjQueryjavascriptでの記述で取得できるけど、Playwrightは独特な記法になるということだったので、特段問題なさそうだった。

Playwrightをインストールする

npm install -D @playwright/test

長いプロジェクトでnodeのバージョンがv16.13.2だったので、

m WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: '@playwright/test@1.49.1',
npm WARN EBADENGINE   required: { node: '>=18' },
npm WARN EBADENGINE   current: { node: 'v16.13.2', npm: '8.1.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'playwright@1.49.1',
npm WARN EBADENGINE   required: { node: '>=18' },
npm WARN EBADENGINE   current: { node: 'v16.13.2', npm: '8.1.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'playwright-core@1.49.1',
npm WARN EBADENGINE   required: { node: '>=18' },
npm WARN EBADENGINE   current: { node: 'v16.13.2', npm: '8.1.2' }
npm WARN EBADENGINE }

しっかり怒られた。

これを機にnodeのバージョンを上げることにする。

$ node -v
v22.13.0

色々な依存関係を解消しつつ、最新LTSまで上げた。

node_modulesを最新化し、

npx playwright install

Playwrightを初期化する。 大量のエラーが吐き出され、TLS/SSL 証明書の検証に失敗した。

export NODE_TLS_REJECT_UNAUTHORIZED=0
npx playwright install

を実行する。

NODE_TLS_REJECT_UNAUTHORIZEDは、Node.jsHTTPS通信を行う際に使用する環境変数で、0にすると、サーバー証明書の有効性が検証されなくなる。

ChromiumFirefoxWebkitFFMPEGがインストール完了した。

Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.

という警告が出ていたので、

export NODE_TLS_REJECT_UNAUTHORIZED=1

でサーバー証明書を再度有効にした。

Playwrightのテストファイルを実行まで

テストファイルの作成

tests/にテストファイルを作成する。

import { test, expect } from '@playwright/test';

test('ホームページが正しく表示されることを確認する', async ({ page }) => {
  // アプリケーションのURL
  await page.goto('http://localhost:4200');

  // タイトルが表示されていることを確認
  await expect(page).toHaveTitle(/Angular App/);

  // テキストが表示されているか確認
  const header = page.locator('h1');
  await expect(header).toHaveText('Welcome to Angular App!');
});

トライする

上記をnpx playwright testで実行したところ、

ReferenceError: describe is not defined

   at src\app\template\sheet\sheet.component.spec.ts:5

  3 | import { SheetComponent } from './sheet.component';
  4 |
> 5 | describe('SheetComponent', () => {
    | ^
  6 |   let component: SheetComponent;
  7 |   let fixture: ComponentFixture<SheetComponent>;
  8 |
    at Object.<anonymous> (C:\dev\path\sheet.component.spec.ts:5:1)

というエラーが大量にでた。 どうやら、標準のユニットテストと混合しているらしい。

エラーと格闘し成功まで

tests/以下に置いていることが影響している気がしたので、tests/e2e以下にファイルを置いて再実行したところ、何も変わらない。

色々調べてみた感じ、playwright.config.tsが不足しているようだったので、

import { PlaywrightTestConfig } from '@playwright/test';

// PlaywrightTestConfig型で設定オブジェクトを定義
// この型定義により、設定オブジェクトの構造が保証され、TypeScriptの補完機能が利用可能
const config: PlaywrightTestConfig = {
  // テストファイルが配置されているディレクトリを指定
  // ./tests 以下のすべての .spec.ts ファイルがテスト対象となる
  testDir: './tests/e2e',

  // テストのタイムアウト時間を30秒(30000ミリ秒)に設定
  // 1つのテストケースがこの時間を超えると、タイムアウトエラーが発生
  timeout: 30000,

  // テスト失敗時の再試行回数を2回に設定
  // テストが失敗した場合、最大2回まで再実行される
  retries: 2,

  // テスト実行時の共通設定
  use: {
    // テスト実行時のベースURLを設定
    // page.goto('/path')とした場合、http://localhost:4200/path にアクセスする
    baseURL: 'http://localhost:4200',

    // トレース(実行ログ)の設定
    // 'on-first-retry': 最初の再試行時にのみトレースを記録
    // トレースには実行時のスクリーンショットやネットワークリクエストなどが含まれる
    trace: 'on-first-retry',

    // スクリーンショットの設定
    // 'only-on-failure': テストが失敗した場合のみスクリーンショットを保存
    screenshot: 'only-on-failure',
  },

  // テストを実行するブラウザプロジェクトの設定
  // 複数のブラウザでテストを実行することで、クロスブラウザテストが可能
  projects: [
    {
      // Chromeブラウザでのテスト設定
      name: 'Chrome',
      use: {
        // Chromiumベースのブラウザを使用
        // Chromium は Chrome の開発版で、テスト自動化に適している
        browserName: 'chromium',
      },
    },
    {
      // Firefoxブラウザでのテスト設定
      name: 'Firefox',
      use: {
        browserName: 'firefox',
      },
    },
    {
      // Safariブラウザでのテスト設定
      // WebKitはSafariのエンジンを使用
      name: 'Safari',
      use: {
        browserName: 'webkit',
      },
    },
  ],
  // レポートを作成する
  reporter: [
    ['html', { open: 'always' }],
    ['json', { outputFile: 'test-results/results.json' }],
  ],
};

// 設定オブジェクトをエクスポート
// この設定は npx playwright test コマンド実行時に自動的に読み込まれる
export default config;

ルートに追加したところ、テストを通すことができた。 そしてレポートのHTMLが作成されるので、結果を見ることができる。