📷
jest-puppeteerとjest-image-snapshotを使ってVisual Regression Testingを試してみる
はじめに
以下の記事でJestでe2eテストと画像比較テストを実装出来たので、今回はそれらを応用してVisual Regression Testingを実現してみたいと思います。
開発言語は引き続きTypeScriptになります。
対象読者
- Jestの実装経験がある方
- e2eテストに興味がある方
- Visual Regression Testingに興味のある方
Visual Regression Testingとは
- 日本語では画像回帰テストと訳せます。
- 画像の差分を検出するスナップショットテストです。
- HTMLのスナップショットテストとは違い実際の画像を比較するためデザイン崩れなどをチェックすることが出来ます。
作業方針
以下の記事に対して、jest-image-snapshotを導入する形で進めます。
動作環境
- Node.js - 14.x
- Yarn - 1.22.x
- Jest - 27.5.x
- ts-jest - 27.1.x
- TypeScript - 4.5.x
- jest-puppeteer - 6.1.x
- jest-image-snapshot - 4.5.x
- @types/jest - 27.4.x
- @types/puppeteer - 5.4.x
- @types/jest-image-snapshot - 4.3.x
- lite-server - 2.6.x (テスト用WEBサイトとして使用)
サンプルコード
テスト用WEBサイトを構築
テスト環境の設定
test/jest-setup.ts
import { toMatchImageSnapshot } from 'jest-image-snapshot';
// jest-image-snapshotをJestのexpectで使用出来るようにする
expect.extend({ toMatchImageSnapshot });
jest.config.js
module.exports = {
preset: 'jest-puppeteer',
moduleFileExtensions: ['js', 'ts'],
transform: {
'^.+\\.ts$': 'ts-jest',
},
testMatch: ['<rootDir>/test/**/*.+(ts|js)'],
// jestのsetupファイルとしてjest-setup.tsを追加
setupFilesAfterEnv: ['./test/jest-setup.ts'],
// jest-setup.tsをテスト対象から除外
modulePathIgnorePatterns: ['jest-setup.ts'],
};
テストコード実装
test/sample.test.ts
describe('Sample test', () => {
beforeEach(async () => {
await page.goto('http://localhost:8000');
});
it('screenshot', async () => {
// ページのスクリーンショットを保存
const image = await page.screenshot();
// スクリーンショットと画像スナップショットを比較
expect(image).toMatchImageSnapshot();
});
it('type test', async () => {
const inputText = 'hoge';
await page.type('#txt', inputText);
const actual = await page.$eval('input[id="txt"]', (el) => (el as HTMLInputElement).value);
expect(actual).toBe(inputText);
// ページのスクリーンショットを保存
const image = await page.screenshot();
// スクリーンショットと画像スナップショットを比較
expect(image).toMatchImageSnapshot();
});
});
- puppeteerのスクリーンショット保存機能で画像データを作成して、jest-image-snapshotの画像スナップショットとの比較機能で差分チェックを行います。
動作確認
初回テスト実行時
- テストが成功してスナップショットが出力されたとログ出力されます。
-
test/__image_snapshots__
ディレクトリに画像スナップショットファイルが生成されます。
2回目以降画像差分がある場合
テストコードの修正
以下のコードに修正します。
test/sample.test.ts
describe('Sample test', () => {
...省略
it('type test', async () => {
// hoge -> hogeeee
const inputText = 'hogeeee';
await page.type('#txt', inputText);
const actual = await page.$eval('input[id="txt"]', (el) => (el as HTMLInputElement).value);
expect(actual).toBe(inputText);
// ページのスクリーンショットを保存
const image = await page.screenshot();
// スクリーンショットと画像スナップショットを比較
expect(image).toMatchImageSnapshot();
});
});
テスト実行
-
toMatchImageSnapshot
の箇所でテストが失敗します。
-
test/__image_snapshots__/__diff_output__/
ディレクトリに画像の比較結果ファイルが出力されます。
画像比較結果ファイル
- スナップショット画像、DIFF画像、テスト実行時の画像の順で並んだ画像ファイルが出力されます。
ソースコード一式
おわりに
- jest-puppeteerとjest-image-snapshotを使用することで簡単にVisual Regression Testingが実現出来ました。
- リリースのたびに画面崩れが頻発するサイトの場合、まずはjest-puppeteerとjest-image-snapshotを使ってデグレチェックをしてみてはいかがでしょうか。
参考URL
Discussion