visual-regression-testing について
visual-regression-testingは、UIコンポーネントやページに意図しない見た目の変化がないか確認するスキルです。Playwrightとjest-image-snapshotでスクリーンショットをバージョン管理された基準画像と比較し、プルリクエスト検査、基準画像の更新、差分レポート作成を行います。
主な機能
- 01基準スクリーンショットの作成と管理
- 02スクリーンショットと基準画像の比較
- 03複数の画面サイズとテーマのテスト
- 04GitHub Actionsでのビジュアル検査
- 05差分レポートの生成とアップロード
- 06比較しきい値の設定
活用シーン
- 01プルリクエストで意図しないUI変更を検出
- 02変更の承認前にビジュアル差分を確認
- 03コンポーネントのレスポンシブ表示をテスト
- 04意図したデザイン変更後に基準画像を更新
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jgtolentino/ insightpulse-odoo --skill visual-regression-testingインストール後、Claude Code で/visual-regression-testingを入力して読み込まれたか確認します。
詳細
ビジュアルリグレッションテスト
このスキルでは、UI コンポーネントの意図しない視覚的な変更を検出し、視覚的なバグが本番環境にマージされるのを防ぐための、包括的なビジュアルリグレッションテスト機能を提供します。
概要
ビジュアルリグレッションテストは、次の手順で行います。
- 正常な状態のコンポーネントやページのスクリーンショット(ベースライン)を撮影します
- コード変更後に新しいスクリーンショットを撮影します
- 新しいスクリーンショットとベースラインをピクセル単位で比較します
- 人による確認が必要な差分を検出します
フレームワーク:Playwright + jest-image-snapshot 手法:Ant Design のビジュアルリグレッションテスト手法をベースにしています
主な機能
1. スクリーンショットのベースライン管理
視覚的な比較の基準となるベースラインスクリーンショットを作成、更新します。
実装:tests/shared/imageTest.tsx
主な機能:
- すべてのコンポーネントデモのベースラインを自動撮影
- バージョン管理されたベースラインの保存
- 意図的な変更があった場合にベースラインを簡単に更新
- 複数のビューポートサイズとテーマに対応
2. ビジュアル比較テスト
実装:scripts/visual-regression/
テストの基本的なワークフロー:
// Example structure from tests/shared/imageTest.tsx
import { test, expect } from '@playwright/test';
test('component visual regression', async ({ page }) => {
await page.goto('http://localhost:5173/component-demo');
await page.waitForLoadState('networkidle');
// Take screenshot and compare with baseline
const screenshot = await page.screenshot();
expect(screenshot).toMatchImageSnapshot({
customSnapshotsDir: '__image_snapshots__',
customDiffDir: '__image_snapshots__/diff',
threshold: 0.1, // 0.1% pixel difference tolerance
});
});
3. CI/CD との統合
実装:.github/workflows/visual-regression-*.yml
ワークフローファイル:
visual-regression-pr.yml- プルリクエストで実行しますvisual-regression-baseline.yml- main ブランチでベースラインを更新しますvisual-regression-report.yml- 差分レポートを生成してアップロードします
PR のワークフロー:
- コードをチェックアウトし、依存関係をインストールします
- ローカルサーバーを起動します
- ビジュアルリグレッションテストを実行します
- 差分が見つかった場合:
- 差分スクリーンショットを生成します
- アーティファクトを GitHub にアップロードします
- 視覚的な差分プレビューを PR にコメントします
- チェックを失敗としてマークします
- 差分がなければ、チェックを成功としてマークします
ベースライン更新のワークフロー:
- マージ後、main ブランチで実行します
- すべてのベースラインスクリーンショットを再生成します
- 更新したベースラインをリポジトリにコミットします
ファイル構成
.github/workflows/
├── visual-regression-pr.yml # PR visual checks
├── visual-regression-baseline.yml # Baseline updates
└── visual-regression-report.yml # Diff reporting
tests/shared/
└── imageTest.tsx # Baseline screenshot utilities
scripts/visual-regression/
├── capture-baselines.ts # Generate baseline screenshots
├── compare-screenshots.ts # Compare current vs baseline
├── generate-report.ts # Create HTML diff report
└── upload-to-storage.ts # Upload to OSS/S3
__image_snapshots__/
├── baseline/ # Baseline screenshots
├── current/ # Latest test screenshots
└── diff/ # Difference highlights
使用パターン
コンポーネント開発の場合
新しいコンポーネントを開発するとき:
# 1. Create component and demos
npm run dev
# 2. Generate initial baseline
npm run visual:baseline
# 3. Make changes
# ... edit component code ...
# 4. Run visual regression test
npm run visual:test
# 5. Review diffs (if any)
npm run visual:report
# 6. Update baseline if changes are intentional
npm run visual:update-baseline
PR レビューの場合
レビュー担当者は次の操作を行えます。
- ビジュアルリグレッションの失敗がないか、CI のステータスを確認します
- PR のコメントにあるアーティファクトのリンクをクリックします
- ビジュアル差分レポートを確認します
- 視覚的な影響に基づいて、承認または変更をリクエストします
CI/CD パイプラインの場合
# Example from .github/workflows/visual-regression-pr.yml
name: Visual Regression Testing
on:
pull_request:
branches: [main, develop]
jobs:
visual-regression:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Install Playwright
run: npx playwright install --with-deps chromium
- name: Start dev server
run: npm run dev &
- name: Wait for server
run: npx wait-on http://localhost:5173
- name: Run visual regression tests
run: npm run visual:test
- name: Upload diff artifacts
if: failure()
uses: actions/upload-artifact@v4
with:
name: visual-diffs
path: __image_snapshots__/diff/
- name: Generate report
if: failure()
run: npm run visual:report
- name: Comment PR with results
if: failure()
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const report = fs.readFileSync('visual-report.md', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: report
});
ベストプラクティス
1. ベースライン管理
- ベースラインをバージョン管理する:ベースラインスクリーンショットを git にコミットします
- 選択的に更新する:意図的な視覚的変更がある場合にのみ、ベースラインを更新します
- 更新内容を記録する:PR の説明にベースラインの更新を記載します
- プラットフォーム間の一貫性を保つ:ローカルではなく、CI 環境でベースラインを生成します
2. テストの作成
- 状態が安定するまで待つ:常に
page.waitForLoadState('networkidle')を使用します - 動的なコンテンツを隠す:タイムスタンプ、アニメーション、ランダムなデータをマスクします
- 重要な経路をテストする:ユーザー向けのコンポーネントに焦点を当てます
- 複数のビューポートを使用する:レスポンシブのブレークポイントをテストします
- テーマのバリエーションを確認する:該当する場合は、ライトモードとダークモードをテストします
3. しきい値の設定
// Strict comparison for critical UI
expect(screenshot).toMatchImageSnapshot({ threshold: 0.01 });
// Relaxed for minor anti-aliasing differences
expect(screenshot).toMatchImageSnapshot({ threshold: 0.1 });
// Very relaxed for charts/animations
expect(screenshot).toMatchImageSnapshot({ threshold: 0.5 });
4. パフォーマンスの最適化
- 並列実行:複数のワーカーでテストを並列実行します
- 選択的なテスト:PR では影響を受けるコンポーネントのみをテストします
- ベースラインの差分更新:変更されていないベースラインをキャッシュして再利用します
- ヘッドレスモード:CI では常にヘッドレスモードで実行します
5. 偽陽性の削減
偽陽性が発生する一般的な原因:
- OS によるフォント描画の違い
- アンチエイリアスの差異
- アニメーションのタイミング
- ブラウザーのバージョンの違い
- システムフォント
対策:
- 一貫した環境を確保するために Docker を使用します
- CSS でアニメーションを停止します
- 一貫したバージョンのブラウザーを使用します
- 軽微な差異についてはしきい値を引き上げます
既存のテストとの統合
ビジュアルリグレッションテストは、既存のテスト戦略を補完します。
Unit Tests (Jest)
↓
Component Tests (React Testing Library)
↓
Visual Regression (Playwright + jest-image-snapshot)
↓
E2E Tests (Playwright)
↓
Manual QA
トラブルシューティング
「スクリーンショットが一致しないのに、見た目は同じ」
原因:プラットフォーム固有の描画の違い 解決策:
expect(screenshot).toMatchImageSnapshot({
failureThreshold: 0.01,
failureThresholdType: 'percent'
});
「依存関係の更新後にベースラインが古くなっている」
原因:ライブラリの更新によってコンポーネントのスタイルが変更されました 解決策:
# Review changes first
npm run visual:test
# Update all baselines if changes are expected
npm run visual:update-baseline
「CI は失敗するが、ローカルのテストは成功する」
原因:環境が異なります(フォント、OS、ブラウザーのバージョン) 解決策:Docker または GitHub Actions をローカルで使用します
# Run in Docker matching CI environment
docker run -v $(pwd):/app -w /app mcr.microsoft.com/playwright:v1.40.0 npm run visual:test
参考資料
実装ファイル
.github/workflows/visual-regression-*.yml- CI/CD ワークフローtests/shared/imageTest.tsx- ベースラインスクリーンショットの実装scripts/visual-regression/- テストコードとユーティリティ
外部リソース
- Ant Design のビジュアルリグレッション - 元の手法
- Playwright のスクリーンショット - スクリーンショット API のドキュメント
- jest-image-snapshot - スナップショットマッチャー
- Argos CI - ビジュアルテストプラットフォーム(Ant Design で使用)
高度な機能
マルチブラウザーテスト
// Test across Chromium, Firefox, and WebKit
import { devices } from '@playwright/test';
const browsers = ['chromium', 'firefox', 'webkit'];
for (const browser of browsers) {
test(`visual regression on ${browser}`, async ({ playwright }) => {
const browserInstance = await playwright[browser].launch();
const page = await browserInstance.newPage();
// ... test logic
});
}
レスポンシブテスト
// Test multiple viewports
const viewports = [
{ width: 375, height: 667, name: 'mobile' },
{ width: 768, height: 1024, name: 'tablet' },
{ width: 1920, height: 1080, name: 'desktop' },
];
for (const viewport of viewports) {
test(`visual regression ${viewport.name}`, async ({ page }) => {
await page.setViewportSize(viewport);
// ... test logic
});
}
コンポーネントの分離
// Test individual component variants
const variants = ['default', 'primary', 'danger', 'disabled'];
for (const variant of variants) {
test(`button ${variant} variant`, async ({ page }) => {
await page.goto(`http://localhost:5173/button/${variant}`);
await page.waitForLoadState('networkidle');
const screenshot = await page.locator('[data-testid="button"]').screenshot();
expect(screenshot).toMatchImageSnapshot({
customSnapshotIdentifier: `button-${variant}`
});
});
}
エージェントの機能
ユーザーがビジュアルリグレッションテストをリクエストした場合、エージェントは次の作業を行います。
-
インフラストラクチャのセットアップ
- GitHub Actions ワークフローを作成する
- Playwright と jest-image-snapshot を設定する
- ベースラインのディレクトリ構成をセットアップする
- よく使う操作のための npm スクリプトを追加する
-
テストの生成
- 各コンポーネントのテストファイルを作成する
- 適切なしきい値を設定する
- 動的コンテンツのマスキングに対応する
- 複数のビューポートでのテストをセットアップする
-
CI/CD との統合
- PR チェックを設定する
- ベースライン更新のワークフローをセットアップする
- アーティファクトのアップロードを設定する
- 差分プレビューを含む PR コメントを追加する
-
ドキュメントの提供
- ベースラインの更新手順を文書化する
- トラブルシューティングガイドを作成する
- よくあるシナリオの例を追加する
- しきい値の設定方法を文書化する
例:完全な実装
完全な実装例については、次のファイルを参照してください。
.github/workflows/visual-regression-pr.yml:1- PR ワークフロー全体tests/shared/imageTest.tsx:1- ベースラインスクリーンショットのユーティリティscripts/visual-regression/compare-screenshots.ts:1- 比較ロジック
このスキルを使うことで、本番環境に到達する前に視覚的なバグを検出する包括的なビジュアルリグレッションテストを実施し、アプリケーション全体で UI の一貫性を維持できます。