🧪

PlaywrightでUI視覚検証を自動化

に公開

最近、らくしふのある画面に対して E2E テストを書いていたのですが、その画面ではレイアウトの見た目がとても重要でした。機能的なテストはすべてパスしていましたが、スタイルの崩れがないか毎回手動で確認する必要がありました。
そんなときに見つけたのが、Playwright のスナップショットテストです。これを使えば、UI の見た目の変化を自動で検出でき、視覚的なリグレッションを簡単に防ぐことができます。

Playwrightのスナップショットテストとは?

Playwright のスナップショットテストは、テスト中に撮影されたスクリーンショットを比較することで、アプリケーションの視覚的な変更を自動的に検出する機能です。
初回の実行時には、ベースライン画像(基準となるスクリーンショット)を保存します。その後のテスト実行時には、再度スクリーンショットを撮影し、ベースライン画像とピクセル単位で比較します。

差分が検出された場合、そのテストは失敗します。これにより、予期しない UI の変更を本番環境にリリースする前にキャッチできます。
レイアウトのズレ、スタイルの崩れ、コンポーネントの破損などを検知するのに特に有効です。

スナップショットテストの始め方

スナップショットの保存先を設定する

デフォルトでは、Playwright はスナップショット画像を .playwright フォルダに保存しますが、大規模なプロジェクトでは管理が難しくなることがあります。
そのため、playwright.config.tssnapshotPathTemplate オプションを使って、保存先をカスタマイズするのがおすすめです。

以下のように設定します:

// playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    // テストファイルごとに専用フォルダにスナップショットを保存
    snapshotPathTemplate: './screenshots/{testFilePath}/{arg}{ext}',
  },
});

この設定を使うことで、screenshots/ フォルダ内にテストファイルごとの構造でスナップショットが整理されます。

テストの書き方

以下の例でスナップショットテストの基本を見てみましょう。

const targetArea = page.locator('.target-section');

await expect(page.getByText('Some visible text')).toBeVisible();
// 特定のセクションをスナップショット撮影。動的部分はマスクし、差分許容率も指定
await expect(targetArea.first()).toHaveScreenshot('target-section.png', {
  mask: [
    page.locator('.dynamic-date'),
    page.locator('.changing-header'),
  ],
  maxDiffPixelRatio: 0.02,
});

このテストでは、まず画面の読み込み完了を確認するために特定のテキストが表示されているかチェックします。
その後、対象エリア(.target-section)のスクリーンショットを撮り、動的に変わる部分をマスク(非表示)し、最大 2% の差分まで許容して比較を行います。

スナップショットテストのオプション

よく使う主なオプションは以下の通りです。

mask
スナップショット撮影時に隠したり無視したりしたい要素のリストです。
日付やヘッダーのように動的に変わる部分をマスクして、誤検知を防ぎます。

maxDiffPixelRatio
ベースライン画像と現在のスクリーンショット間で許容するピクセル差の割合です。
例えば 0.02 は、最大で全体の 2% までの差分を許容します。

他にも、ページ全体をキャプチャする fullPage や、ピクセル単位の差分閾値を設定する threshold などのオプションがあります。
詳しくは公式ドキュメントをご覧ください: Playwright docs.

スナップショットの更新方法

UI が意図的に変更された場合(デザインの刷新や新機能追加など)、スナップショットテストが失敗することがあります。
これは、基準となるスクリーンショット(ベースライン画像)が古くなっているためです。
そのような場合は、新しい UI に合わせてスナップショットを更新する必要があります。

スナップショットを更新するには

以下の --update-snapshots(または -u)オプションをつけてテストを実行すると、現在の画面を新たな基準画像として保存します。

npx playwright test test_name.spec.ts --update-snapshots

その他の便利なオプション

すべてのテストのスナップショットを更新する

npx playwright test --update-snapshots

新しく追加されたスナップショットのみを更新する(新しいテストのデフォルト動作)

npx playwright test --update-snapshots=missing

差分があっても全てのスナップショットを更新する

npx playwright test --update-snapshots=all

Final Thoughts

Playwright のスナップショットテストは、テストスイートに軽量ながら強力な視覚検証の層を加えます。
一度設定すれば、手動の手間をかけずに予期しない UI の変化を早期に検出できます。

もし既に Playwright を使っているなら、スナップショットテストを追加するだけで、本番環境での大きな見た目のトラブルを防げるようになります。


参考資料


https://x-bit.co.jp/recruit/
https://herp.careers/v1/xbit
https://note.com/xbit_recruit

クロスビットテックブログ

Discussion