こんにちは。Eight事業部で主にフロントエンドを担当している青山です。
今回はEightのWebフロントエンドコンポーネント集にVisual Regression Testingを導入した事例を紹介します。
他社さんの事例や勉強会を見るに敷居も下がってきているようで、遅ればせながらDX(開発者体験)向上を見据えて環境を構築していきました。
Visual Regression Testing とは
Visual Regression Testing (以下、VRT) は日本語で画像回帰テストと呼ばれています。対象の修正前後の画像を比較し、差分がないこと、もしくは差分が正しいことをチェックします。 GUIアプリケーションの場合、最終的にユーザーが触れるのは画面であり、この状態をスナップショットでチェックできるのはとても安心できるものだと思います。
Eightのコンポーネント集
今回導入対象として目をつけたのがEight内のコンポーネント集です。その内容について簡単にご紹介します。
EightではWebフロントエンドの構築にReactを利用しています。
Reactは自体はとても使いやすいUIライブラリですが、決まりごとがない状態でチーム開発を進めていくとカオスになっていきます。
特に、似たようなスタイルの乱立や同じスタイルでもそれぞれでハードコーディングされているなど、サービスの統一的なデザインの障害になってきます。
そこでスタイルガイド*1の一部としてReact用のコンポーネント集を準備しました。経緯などについては以前、弊社のイベントで少しご紹介しています。
コンポーネント集は以下の技術スタックで作られており、GitHub上で管理されています。
- React
- TypeScript
- CSS Modules
- Storybook
- Jest
StorybookはReactをはじめとしたUIコンポーネントをカタログ化して確認できるツールです。
コンポーネント集ではStorybookのstoryとしてコンポーネントの状態ごとにUIを確認できるようになっています。 GitHub Actionsによるワークフローを組んでおり、CI時に静的ページとしてS3にデプロイしています。 さらにその流れの中でPR上に確認用のURLがコメントされるようにしており、「デモ画面」を見れば誰でも変更内容を触って確認できます。
VRTの導入
すでにJestによるDOMの差分チェックは行っていましたが、レビューなどで常に目視確認するのは少し無理があるように思います。
そこで先にも述べたようなメリットを享受できるVRTの導入を進めることにしました。
Storybookの準備が整っていたこともあり、Storycap + reg-suit という組み合わせでのVRT環境としました。
Storycap
StorycapはStorybookのstoryごとの画面キャプチャを保存してくれるStorybookのアドオンです。
サイト内のManaged modeに記載のとおり、以下の手順のみで準備完了です。
yarn add -D storycap
- stroybookのaddonにstorycapを追加
- storybookの設定にdecorator (
withScreenshot
) を追加
reg-suit
reg-suitは画像の比較を行なうためのVRT用ツールで、今回はStorycapの出力を利用します。
reg-suitのプラグイン機能を利用すると、以下のようなことを一括でやってくれるのでとても便利です。
- reg-keygen-git-hash-plugin:GitHub上のどのコミットでのスナップショットを比較するかを決定
- reg-publish-s3-plugin:スナップショットや比較情報をS3にアップロード
- reg-notify-github-plugin :GitHub PRのコメントで比較情報を通知
こちらもStorycapと同様にサイト内のGetting Startedに従って、インストールと設定をしていきます。
npm install -g reg-suit
reg-suit init --useYarn
質問に対話形式で答えていくことで設定ファイルが出来上がります。
以下が今回作成された設定ファイル regconfig.json
です。
{ "core": { "workingDir": ".reg", "actualDir": "__screenshots__", "thresholdRate": 0.001, "ximgdiff": { "invocationType": "client" } }, "plugins": { "reg-keygen-git-hash-plugin": {}, "reg-notify-github-plugin": { "prComment": true, "prCommentBehavior": "default", "setCommitStatus": false, "clientId": "{GitHub AppクライアントID}" }, "reg-publish-s3-plugin": { "bucketName": "{バケット名}", "pathPrefix": "{バケット内パス}", "acl": "private" } } }
reg-notify-github-pluginはGitHub Appになっており、 上記コマンドの中でインストールやクライアントIDの取得を行います。 今回は上記設定でCIステータスへの反映を止めています。PRでの不要な混乱を避けるためでしたが、renovateによる自動マージを実施している部分などは反映しても良さそうだと感じています。
ワークフロー
今回はCIワークフローとしてGitHub Actionsを利用しています。
CIサービスの設定方法も各種揃っているので参考にして設定していきます。
Eightではすでにワークフローでstorybookのサイトを作成してあったので、既存の設定に以下を追記しました。*2
- name: add JP font run: | sudo apt-get install fonts-ipafont-gothic fonts-ipafont-mincho - name: workaround for detached HEAD run: | git checkout ${GITHUB_REF#refs/heads/} || git checkout -b ${GITHUB_REF#refs/heads/} && git pull - name: capture snapshots run: | yarn storycap http://127.0.0.1:8080 --serverCmd "npx http-server storybook-static" - name: run reg-suit run: | yarn reg-suit run
これで、これまでのワークフローに画像差分確認が追加され、以下のようになります。
できたもの
GitHub ActionsでPRに以下のようなコメントが差し込まれるようになります。 青い丸が差分がないもの、赤い丸が差分が生じたものを示します。 今回意図的にアイコンを入れ替えたPRを作成してみました。
レポートのHTMLで以下のようなサマリと画像比較ページを確認できます。 お見せしている画像はblendモードで変更前後を一枚の画像で表現していますが、その他にも変更前後を横並びで表示する2upモードなど、reg-suitからとても見やすいレポートが提供されます。
まとめ
EightでのStorybookによるVRTの導入事例についてご紹介しました。
素晴らしいOSSを組み合わせることで、準備次第では本当にサクッと導入できるものになっているんだという実感があります。
今回の例はコンポーネント集というシンプルなものへの適用ですが、サービス本体にも適用できるようになれば、スタイル変更の影響などが明確になり、恐る恐るCSSを変更することが減るでしょう。
これからVRT導入することを検討されている方への助けになれば幸いです。