メインコンテンツへスキップ

視覚的な比較

はじめに

Playwright Testには、await expect(page).toHaveScreenshot() を使用してスクリーンショットを生成し、視覚的に比較する機能が含まれています。初回実行時、Playwrightテストは参照スクリーンショットを生成します。それ以降の実行では、参照と比較されます。

example.spec.ts
import { test, expect } from '@playwright/test';

test('example test', async ({ page }) => {
await page.goto('https://playwright.dokyumento.jp');
await expect(page).toHaveScreenshot();
});
警告

ブラウザのレンダリングは、ホストOS、バージョン、設定、ハードウェア、電源(バッテリーかACアダプターか)、ヘッドレスモード、その他の要因によって異なる場合があります。一貫性のあるスクリーンショットを得るには、ベースラインスクリーンショットが生成されたのと同じ環境でテストを実行してください。

スクリーンショットの生成

上記を初めて実行すると、テストランナーは次のように表示します

Error: A snapshot doesn't exist at example.spec.ts-snapshots/example-test-1-chromium-darwin.png, writing actual.

これはまだゴールデンファイルがなかったためです。このメソッドは、2つの連続するスクリーンショットが一致するまで多数のスクリーンショットを撮影し、最後のスクリーンショットをファイルシステムに保存しました。これでリポジトリに追加する準備ができました。

ゴールデン期待値が格納されているフォルダの名前は、テストファイルの名前で始まります

drwxr-xr-x  5 user  group  160 Jun  4 11:46 .
drwxr-xr-x 6 user group 192 Jun 4 11:45 ..
-rw-r--r-- 1 user group 231 Jun 4 11:16 example.spec.ts
drwxr-xr-x 3 user group 96 Jun 4 11:46 example.spec.ts-snapshots

スナップショット名 example-test-1-chromium-darwin.png はいくつかの部分で構成されています

  • example-test-1.png - 自動生成されたスナップショット名です。または、toHaveScreenshot()メソッドの最初の引数としてスナップショット名を指定することもできます。

    await expect(page).toHaveScreenshot('landing.png');
  • chromium-darwin - ブラウザ名とプラットフォームです。スクリーンショットは、ブラウザやプラットフォームによってレンダリング、フォントなどが異なるため、それぞれ異なるスナップショットが必要になります。設定ファイルで複数のプロジェクトを使用している場合、chromiumの代わりにプロジェクト名が使用されます。

スナップショット名とパスは、Playwright設定ファイルのtestConfig.snapshotPathTemplateで設定できます。

スクリーンショットの更新

ページが変更された場合など、参照スクリーンショットを更新する必要がある場合があります。これは--update-snapshotsフラグを使用して行います。

npx playwright test --update-snapshots

snapshotNameは、expect().toHaveScreenshot(['relative', 'path', 'to', 'snapshot.png'])のように、スナップショットファイルへのパスセグメントの配列も受け入れることに注意してください。ただし、このパスは各テストファイルのスナップショットディレクトリ(つまりa.spec.js-snapshots)内に留まる必要があり、そうでない場合はエラーが発生します。

オプション

maxDiffPixels

Playwright Testはpixelmatchライブラリを使用します。さまざまなオプションを渡してその動作を変更できます。

example.spec.ts
import { test, expect } from '@playwright/test';

test('example test', async ({ page }) => {
await page.goto('https://playwright.dokyumento.jp');
await expect(page).toHaveScreenshot({ maxDiffPixels: 100 });
});

プロジェクト内のすべてのテストでデフォルト値を共有したい場合は、Playwright設定で、グローバルまたはプロジェクトごとに指定できます。

playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
expect: {
toHaveScreenshot: { maxDiffPixels: 100 },
},
});

stylePath

スクリーンショットを撮る際に、カスタムスタイルシートをページに適用できます。これにより、動的または不安定な要素を除外できるため、スクリーンショットの決定性が向上します。

screenshot.css
iframe {
visibility: hidden;
}
example.spec.ts
import { test, expect } from '@playwright/test';

test('example test', async ({ page }) => {
await page.goto('https://playwright.dokyumento.jp');
await expect(page).toHaveScreenshot({ stylePath: path.join(__dirname, 'screenshot.css') });
});

プロジェクト内のすべてのテストでデフォルト値を共有したい場合は、Playwright設定で、グローバルまたはプロジェクトごとに指定できます。

playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
expect: {
toHaveScreenshot: {
stylePath: './screenshot.css'
},
},
});

非画像スナップショット

スクリーンショット以外にも、expect(value).toMatchSnapshot(snapshotName)を使用してテキストや任意のバイナリデータを比較できます。Playwright Testはコンテンツタイプを自動検出し、適切な比較アルゴリズムを使用します。

ここでは、テキストコンテンツを参照と比較しています。

example.spec.ts
import { test, expect } from '@playwright/test';

test('example test', async ({ page }) => {
await page.goto('https://playwright.dokyumento.jp');
expect(await page.textContent('.hero__title')).toMatchSnapshot('hero.txt');
});

スナップショットは、テストファイルの隣の別のディレクトリに保存されます。たとえば、my.spec.tsファイルは、my.spec.ts-snapshotsディレクトリにスナップショットを生成および保存します。このディレクトリはバージョン管理(例: git)にコミットし、変更があった場合はレビューする必要があります。