📝

reg-suitとpuppeteerを使ってローカル環境でVRTを実施してみた

に公開

以前、自分の所属するチームで 「フロントエンド開発のためのテスト入門 今からでも知っておきたい自動テスト戦略の必須知識」 を輪読し疑問点や学びを共有する会を行いました。
https://www.seshop.com/product/detail/25576?srsltid=AfmBOopIaaqxHDqxAQ14zLHInsHSr-nBOwGNBbYUCs4XSLG9F1oF34xj

書籍の中でビジュアルリグレッションテスト(VRT)が紹介されており、概要を理解することはできたのですが、実際に自分が作成したプロジェクトに対して、VRTを導入してみて流れを知りたいと感じました。そのため今回は、ローカル環境で作成した簡単なTodoアプリに対して、reg-suitとpuppeteerを使ってVRTを実施するまでの手順をまとめていこうと思います。

前提

今回説明すること

ローカル環境で作成した 簡単なTodoアプリ に対して、reg-suitとpuppeteerを使ったVRTを実施するまでの手順を説明します。

説明しないこと

以下の説明は省略します。

  • Todoアプリ自体の作成手順
  • reg-suit の詳しい仕組みや解説

1. ツールのインストール

まずは、プロジェクトのディレクトリに移動して、npmを使ってreg-suitとpuppeteerをインストールします。reg-suitはVRTを行うためjsライブラリで、スクリーンショットの差分を自動で比較してくれます。またpuppeteerはNode.js上でブラウザ操作を自動化できるライブラリで、画面の表示やスクリーンショットの撮影をプログラムから実行できるようにしてくれます。
https://pptr.dev/

また、これらのライブラリは本番環境では使用せず、開発やテストのときだけ必要なツールなので、--save-devオプションを付けてインストールすることにします。

cd ~/プロジェクトが存在するディレクトリ
npm install --save-dev reg-suit puppeteer

2. reg-suit設定ファイルの作成

次にreg-suitの設定を行います。
プロジェクトルートにregconfig.jsonというファイルを作成し、以下の内容を記述します。

{
  "core": {
    "workingDir": ".reg",
    "actualDir": "screenshots", 
    "expectedDir": "expected",
    "diffDir": "diff",
    "report": {
      "json": "report.json",
      "html": "report.html"
    },
    "threshold": 0.05,
    "enabledParallel": false,
    "enabledMetrics": false
  },
  "plugins": {
    "reg-keygen-git-hash-plugin": true
  }
}

作成したregconfig.jsonでは、主に以下のような設定を行っています。

  • スクリーンショットの保存場所の指定(screenshots, expected, diff など)
  • 比較時の許容差の設定(threshold: 0.05)
  • レポートの出力形式(HTMLとJSON)

3. スクリーンショット撮影スクリプトの作成

続いて、Puppeteerを使って画面キャプチャを自動で撮るスクリプトを作成します。
プロジェクトルートにcapture-screenshots.jsというファイルを作成してください。
参考: https://github.com/reomin/testNewFeatures/blob/main/frontend/capture-screenshots.js

このスクリプトではPuppeteerでブラウザを立ち上げてテスト対象のページに対してスクリーンショットを撮影します。今回はサンプルとして使用しているTodoアプリの以下の2ページのスクリーンショットを撮影することにしました。

撮影対象:

  • home.png(/)

  • todos.png(/todos)

撮影した画像は、screenshots/ディレクトリに保存されます。


4. package.json にスクリプトを追加する

npm run vrt:init //初回セットアップ
npm run vrt:run //差分チェック
npm run vrt:approve //更新

次に、上のような流れでVRTを実行できるようにpackage.jsonの scriptsに以下のスクリプトを追加します。

"scripts": {
  "capture": "node capture-screenshots.js",
  "vrt:init": "npm run capture && npx reg-suit sync-expected",
  "vrt:run": "npm run capture && npx reg-suit compare",
  "vrt:approve": "npx reg-suit sync-expected"
}

それぞれのスクリプトの役割については以下のとおりです。

  • capture:スクリーンショットを撮影するだけのコマンド
  • vrt:init:初回実行時にベースライン(比較元の画像)を作成
  • vrt:run:最新のスクリーンショットとベースラインを比較して、差分を検出
  • vrt:approve:変更内容を確認したうえで、ベースラインを更新(=変更を承認)

5. 初回スクリーンショットの撮影

準備ができたら、まずは実際にスクリーンショットを撮ってみます。
以下のコマンドを実行します。

npm run capture

コンソールに次のような結果が表示されれば成功です。

✓ home.png saved  
✓ todos.png saved  
All screenshots captured successfully!

これで、2つのページのスクリーンショットが screenshots/ ディレクトリに保存されました。
ここまでで、Puppeteerを使用してVRTで比較するためのが正しく動作していることを確認できました。


6. ベースライン画像の設定

次に、比較の基準となるベースライン画像を作成します。
まずは以下のコマンドを実行します。

npm run vrt:init

このコマンドでは次の処理が行われます。

  1. スクリーンショットの撮影を実行
  2. npx reg-suit sync-expected によって、ベースライン画像の設定を試行

ただし、初回はGitのハッシュ値を検出できずエラーとなるため、手動でベースラインを設定する必要があります。

手動対応

以下のコマンドで、現在撮影したスクリーンショットをベースラインとして登録します。

mkdir -p .reg/expected
cp screenshots/*.png .reg/expected/

これで、現在のスクリーンショットがベースラインとして設定されました。
次回以降はこの画像を基準に、変更後の画面との差分が検出されるようになります。


7. VRTの動作テスト

最後にVRTを実行してみます。
VRT実行のため、以下のコマンドを実行します。

npm run vrt:run

テストが無事に通過し、差分は検出されないことが今回の期待結果であるため、コンソール上に次のような結果が表示されれば成功です🎉

[reg-suit] info Comparison Complete
[reg-suit] info Changed items: 0
[reg-suit] info New items: 0
[reg-suit] info Deleted items: 0
[reg-suit] info Passed items: 2

おわりに

今後は、GitHub ActionsなどのCI環境への組み込みにも挑戦して、運用の幅を広げていきたいと思います。文章の中で間違った表現や内容があればお気軽に教えてください。

Discussion