こんにちは!SmartHRで人事評価機能の開発を担当している、エンジニアのkanekoです。Visual Regression Testを導入して、安心・安全にUIライブラリのアップデートやリファクタが行える環境を整備したので、その取り組みをご紹介します。
「Visual Regression Test 」とは変更前と変更後のコードで対象画面のスナップショットを比較することで、発生したUIの差分を検知して、見た目のリグレッションが発生していないかを検証するフロントエンドのテスト手法の一種です。
差分検知のイメージ
Visual Regression Testを導入するに至った経緯
チームの課題感
私達のチームでは、意図しないレイアウト崩れなどの確認にかなりの手間と時間を取られる問題に悩まされていました。
外部ライブラリをRenovateを使って自動更新するようにしているのですが、リリース前の動作確認でレイアウトが崩れていたり、リグレッションが発生していることに気がつくと、ライブラリの更新を再度やりなおす必要があり、自動更新のメリットがあまり得られていない状態になっていました。
また、フロントエンドのコンポーネントを修正した際にも、すべての利用箇所を目視で確認するようにしていたため、動作確認にかなりの手間がかかってしまっていました。すべての箇所を確認したつもりでも、漏れが発生してしまうというようなこともありました。
チームで検討した解決策
今回この課題についてチームで検討した結果、以下のような状態を目指すことになりました。
- 外部ライブラリの自動更新時に、レイアウト崩れが発生している場合は自動更新させないこと
- 目視しなくてもコンポーネントのデザインやレイアウトの崩れに気付けること
これらを実現するための手法としてVisual Regression Test (以下VRTと記載)の導入を決定しました。
VRTを導入することで、UIの変更を自動で検知することができるようになります。変更があった場合にのみ内容を確認すれば良いので、目視で確認していくよりも高速に、かつ確実に気づくことができます。
また、CIに組み込むことで、Pull Requestのレビュー時に気がつくことができるため、ライブラリの更新時にリグレッションが発生している場合は自動更新されず、手戻りも少なく修正に取り組むことが可能になります。
VRTを入れるにあたって考えたこと
具体的なツールの検討
VRTを導入するにあたって具体的なツールとして以下の2案を検討しましたが、後述する理由から2のツールの組み合わせを利用することになりました。
まず各ツールについて説明します。
Playwrightは、オープンソースのテスト自動化フレームワークとして有名です。Chrome・Firefox・Safari・Edgeなど複数のブラウザをサポートし、豊富なAPIを提供しています。
Storybookは、UIコンポーネントを独立して開発・テストできるオープンソースのツールです。各コンポーネントの状態を視覚的に確認しながら、再利用可能なコンポーネントライブラリを効率的に構築できます。 Chromaticは、Storybookで開発されたUIコンポーネントをクラウド上で管理・共有・レビューできるフリーミアム型のサービスです。VRTを自動化する機能を提供しています。
検討したツールのメリット・デメリットは以下の通りとなっています。
ツール案 | メリット | デメリット |
---|---|---|
Playwright | Storybookなど他ツールに依存せず、単体でお手軽に導入ができる。 既存のE2Eテストで導入していれば学習コストも比較的低い。 | スナップショットの管理は自前で行う必要がある。 CI で実行する場合、差分が検出されてもすぐに目視で確認するのに手間がかかる |
Storybook + Chromatic | セットアップが簡単でキャプチャの取得からデプロイ、差分比較までコマンド1つで実行できる | スナップショットの枚数によって料金が発生する(月5000枚までは無料だが、それ以降は有料になる) |
Storybook + Chromaticを採用した大きな理由としては、SmartHR内の他のチームですでにStorybook + ChromaticでVRTを行っているチームがあり*1、その知見や資産を活かせるメリットが大きかったためです。 また、今回は目視で差分を確認したいという目的に合致していたStorybook + Chromaticの採用を決めました。 E2Eでの利用も考えているような場合は、Playwrightも有力な選択肢になりそうです。
VRTの具体的な導入方法
Stroybook+Chromaticを利用したVRTの具体的な導入方法は以下の通りです。
- VRTを行うためのStorybookを導入する
- Chromaticの準備とCI上でテストを実施する
VRTを行うためのStorybookを導入する
まず、チームとしてはStorybookを導入していなかったので、ここから始めることになりました。そこで課題になったのはどの粒度でStorybookを導入するのが良いか?です。
Storybookを導入する初期は以下の粒度で導入することが多いと思います。
- ボタンやフォント、アイコンなどの小粒度のUIコンポーネント単位
- アトミックデザインで言うところのMoleculesやOrganismsといった中粒度のUIコンポーネント単位
小粒度のUIコンポーネントで入れるとなるとかなり数も多く、VRTが実運用に載るまで時間がかかります。中粒度のUIコンポーネントで入れるのもpropsが多いコンポーネントが多く、状態を把握するのに苦労しそうでした。
そこで選んだのはページ相当のコンポーネント単位でStorybookを入れる方法でした。ページ単位で良いと考えた理由は以下になります。
- ページ相当のコンポーネントが表示出来ると大体のUIコンポーネントの差分を検知できる
- mswでAPI コールする処理を全てモックすればページを表示するのに必要なデータはほぼ用意できる
- react hooksのuseContextを使っているコンポーネントもDecoratorを使ってstory毎にラップすることができる
- Storybookのv6.4 から play 関数が導入されたことによってインタラクティブな操作も可能なので、コンポーネントに含まれているdialogやdropdownなども表示できる
Chromaticの準備とCI上でテストを実施する
Chromaticの準備は至って簡単です。
- Chromatic に飛び、github のアカウントでログインまたはアカウントを作り github を連携
- Add project からリポジトリを選択
- Tokenが発行されるので保存
CIでのVRTの実施は以下のコマンドを実行するだけです。
yarn chromatic
package.jsonに設定したコマンドは以下の通りです。
"build-storybook": "storybook build --quiet", "chromatic": “chromatic --project-token=${CHROMATIC_PROJECT_TOKEN} --only-changed --exit-zero-on-changes --exit-once-uploaded”
chromaticは暗黙的にbuild-storybookを使って、storybookをbuildするようになっているので、package.jsonにbuild-storybookを用意する必要があります。
CIが完了して、Chromaticで差分が検知されると以下のようにUI上で提示されます。
オプションについて
package.jsonに設定したコマンドのオプションについても一部説明を載せておきます。
オプション | 説明 |
---|---|
--exit-zero-on-changes | Pull Requestのステータスがマージ前の必須チェックとして使用され、テストスナップショットがエラーなしでレンダリングされた場合に、パイプラインを止めない為のフラグ。 |
--only-changed | chromaticのTurboSnapというのを有効にするフラグ。GitとWebpackの依存関係グラフを使用して、より迅速なUIテストとレビューのためにビルドを高速化するChromaticの高度な機能らしい。変更されたコンポーネントファイルと依存関係を識別し、それらの変更に関連するストーリーだけをスナップショットする。 |
実際に運用して
導入・運用してみた感想をチームメンバーから聞いてみました!
よかった感想
- UIの差分をStagingとローカルを見比べなくてよくなったので最高
- VRTを整備した副産物としてStoryにテストを書く環境が出来上がったので最高
メンバーからの反応はかなり好評で、外部ライブラリの更新も安定して行えるようになりましたし、レビュー時にレイアウト崩れ周りの確認に割く時間も減らすことができました。
伸びしろ
- (最近は改善傾向にあるけど)やや不安定なのでもうちょいなんとかしたい
スナップショットのタイミングの問題で軽微な差分が出てしまうことがありました。こちらに関してはレンダリングが終わってからスナップショットを取得するようにするなどして少しずつ改善を行っている最中になります。
今後の拡張について
私達のチームでは、レイアウト崩れの課題以外にも、フロントエンドのテストが薄いという課題も抱えていました。Storybookのv6.5 から Interaction testsが可能になったのもあり、今回の資産を使いつつ、インテグレーションテストの導入にも取り組むことになりました。これにより、さらに手動のテスト工数の削減をしつつ、品質の向上の両立に挑戦していきたいと思っています。
まとめ
今回は「Storybook+Chromatic」の組み合わせでVRTを導入し、チームの課題を改善した取り組みを紹介しました。導入に当たって初挑戦のことばかりで苦労もありましたが、無事課題解決に向かうことができてよかったです。また、あわせてフロントエンド全体の品質向上の取り組みにも繋げることができ、当初考えていた以上の効果を得られました。もし同じような悩みを抱えている方がいれば、ぜひVRTの導入を検討してみてください!
We Are Hiring!
SmartHR では一緒に SmartHR を作りあげていく仲間を募集中です! フロントエンドの品質改善などに興味がある方、ぜひ一度カジュアル面談で気軽にお話してみませんか? 詳しくは以下のリンクをご覧ください。
https://hello-world.smarthr.co.jp/
*1:詳細は、「WEB+DB PRESS Vol.134」の特集2「はじめての画像回帰テスト」(宮脇駿著)をご覧ください。