reg-suit + Storycapのビジュアルリグレッションテストをクラウドストレージ不要で構築してみた

この記事は、 KENTEM TechBlog アドベントカレンダー2023 4日目、12月6日の記事です。

こんにちは。KENTEMでフロントエンドを担当している吉村です。

前回、デザイン崩れを恐れずコンポーネント修正をしよう!~BackstopJS編~という記事を投稿しましたが、
新たにビジュアルリグレッションテスト(以下、VRT)を以下のツールで構築しました。

正直なところ、何番煎じですか?という王道の組み合わせに落ち着いた感じがあるので、
他の方のreg-suit導入記事ではあまり見かけなかった、
クラウドストレージを利用せずVRTを実施するためにやったことを中心に紹介したいと思います。

小さいチームでは、VRT試してみたいなと思っても、
いきなりクラウドストレージまで用意するとなるとハードルが高いと思います。
まずは気軽に始めてみたいという方の参考になれば幸いです。

そもそもVRTってなんですか?という方はぜひ前回の記事も読んでみてください。

前回reg-suitを避けていたのに気が変わったの?

私が大きな勘違いをしていたのですが、
reg-suitでは公式からキャプチャの保存用として、
Amazon S3Google Cloud Storage用のプラグインが用意されています。
弊社ではAzureを利用しているため、相性が悪いものだと思い込み、
それ以上、深く調べるのをやめてしまっていました。
ですが、改めてreg-suitStorycapのGitHubを眺めていたところ、
勘違いであることが分かったため、採用に至りました。

前提

Storycapを利用しているため、当然ながらStorybookの導入は必須です。
Storybookの導入から解説すると長くなってしまうため、
Storybookについては導入済みである前提とさせていただきます。

また、start, xcopy等のWindows用コマンドが入っているため、
Windows以外で使うにはコマンドの置き換えが必要です。

構築

必要なパッケージをインストールします。
rimraf, npm-run-allは後に利用します。

npm install --save-dev reg-suit
npm install --save-dev storycap
npm install --save-dev rimraf
npm install --save-dev npm-run-all

◆ reg-suit用設定ファイル(regconfig.json)を作成します。

ximgdiff.invocationTypenoneに設定することがポイントです。
これを指定しない場合、x-img-diff-jsによる差分検知が実行されます。
VRTの結果レポートとしては便利なものなのですが、利用されている技術の問題で、
fileプロトコルではエラーが発生して、結果レポートの閲覧ができなくなります。
そのため今回はOFFにします。
(このように結果レポートを直接ファイルとして開けるようにする対応です。)

{
  "core": {
    "workingDir": ".reg",
    "actualDir": ".storycap/test",
    "thresholdRate": 0,
    "matchingThreshold": 0,
    "enableAntialias": true,
    "ximgdiff": {
      "invocationType": "none"
    }
  }
}

StorycapアドオンをStorybookに追加します。

module.exports = {
  stories: ['../src/**/*.stories.@(js|mdx)'],
  addons: [
    '@storybook/addon-actions',
    '@storybook/addon-links',
    'storycap', // ここを追加します。
  ],
};
import { withScreenshot } from 'storycap';

export const decorators = [
  withScreenshot, // ここを追加します。
];

export const parameters = {
  // ここを追加します。設定は一例です。
  // delayは取得が上手くいかないようであれば数値を増やして調整してください。
  screenshot: {
    delay: 0,
    viewport: {
      width: 600,
      height: 400,
      deviceScaleFactor: 1,
      isMobile: false,
    },
  },
};

.gitignoreを追加します。

.storycap
.reg

package.jsonscriptsを追加します。

これはお好みなのですが、私はオプションとして次のものを指定しています。
{ "ignoreDefaultArgs": ["--hide-scrollbars"] }
これにより、取得するキャプチャにスクロールバーが含まれるようになります。
StorycapChromiumを利用しているのですが、
Chromiumはデフォルトで、スクロールバーを非表示にするというオプションが付いてしまっています。
スクロールバーが正しく出ているかに関しても確認したかったため、
ignoreDefaultArgsを利用してデフォルトで与えられているオプションを無効化しています。
スクロールバーの確認は不要だという方は消してしまってください。

"scripts": {
  "storycap:reference": "npm run setup:storycap:reference http://localhost:6006",
  "storycap:reference-azure": "npm run setup:storycap:reference https://hogefuga",
  "storycap:test": "run-s -c setup:storycap:test setup:reg-suit setup:report-open",
  "storycap:approve": "rimraf .storycap/reference && move .storycap\\test .storycap\\reference",
  "setup:storycap:reference": "rimraf .storycap/reference && storycap -o .storycap/reference --puppeteerLaunchConfig \"{ \\\"ignoreDefaultArgs\\\": [\\\"--hide-scrollbars\\\"] }\"",
  "setup:storycap:test": "rimraf .storycap/test && storycap http://localhost:6006 -o .storycap/test --puppeteerLaunchConfig \"{ \\\"ignoreDefaultArgs\\\": [\\\"--hide-scrollbars\\\"] }\"",
  "setup:reg-suit": "rimraf .reg && xcopy /s /i .storycap\\reference .reg\\expected && reg-suit compare",
  "setup:report-open": "start \"\" \".reg\\index.html\"",
},

使用するコマンドは、以下です。
.storycap配下にデータを保存する形式にしています。
setupから始まるものは、長くなるscriptsの分割用で、他のscriptsから利用するのみです。
scriptsを実行するとどうなるかは使用するときに解説します。

  • storycap:reference
  • storycap:reference-azure(任意)
  • storycap:test
  • storycap:approve

storycap:reference-azureは、必須ではなく、更に言えばAzureでなくてもよいのですが、
いざ修正作業が終わってテストするぞ!と思ったときに、
「そういえばreference取り忘れてるやん・・・ブランチ切り替えて取りに行くのめんどくさ・・・」
となることが度々あったため、
毎日CIでデプロイされているStorybookreferenceとして取り込めるようにしています。
クラウド不要というコンセプトに反した内容にはなるのですが、
実際に利用していて不満に感じたポイントを改善した内容なので紹介しておきます。

使ってみよう

Storybookを立ち上げた状態で、npm run storycap:referenceします。
これで.storycap/referenceに修正前のキャプチャが取得されます。

デザインの変更が検知されるような適当な修正を入れた後で、
次はnpm run storycap:testします。
これで.storycap/testに修正前のキャプチャが取得されます。

そのまま自動でreg-suitの比較処理が走って・・・

無事にreg-suitの結果レポートが表示されました!
自動で結果レポートを開くようにしていますが、
後から見返したいときには、.reg\index.htmlを開いてください。

結果レポートは、5種類の表示方法で詳細な確認ができます。

差分の内容を確認して、問題無ければnpm run storycap:approveします。
testで取得した内容で、referenceが上書きされます。

使ってみた感想

前回の記事でも書きましたが、自分の修正による影響範囲を確認できることで、
自信を持ってプッシュすることができるようになりました。

また、画面デザインに納得がいかない。修正は簡単なんだけど、広範囲に影響する。
そのため、どう修正するか決めかねている。
そんなときに、先に修正してしまってからVRTの差分を共有。
修正前後、差分を見比べながら「こんな感じで変えたいと思いますがどうですか?」とチーム内で相談するという風に使うこともできました。

Storybook導入前提にはなりますが、逆に言うとStorybookさえ書いていればVRT用の追加の設定がほぼ不要なのも嬉しいポイントかと思います。
実行時間もdelayを500msに設定した状態で、約250枚が1分で済むのでスピーディーです。

KENTEMでは、様々な拠点でエンジニアを大募集しています!
建設×ITにご興味頂いた方は、是非下記のリンクからご応募ください。
hrmos.co