はじめに
この記事はSTORES Advent Calendar 2023 19日目の記事です。
こんにちは、 STORES 予約 でエンジニアをしている@tontokoです。 STORES 予約 の開発チームでは月に1回、コードクリーニングタイムと呼ばれる日を設けています。
これは普段なかなか手を付けるタイミングが無かった技術負債や、重要ながら後回しにされているタスクなどを片付けることを目的にしています。 当日は緊急度の高いものを除き普段のプロダクト開発の手を休め、内部品質の向上に集中します。
自分は前回のコードクリーニングタイムに、ビジュアルリグレッションテスト(VRT)をフロントエンドリポジトリに導入しました。
導入の経緯
STORES 予約 ではバックエンドのテストに比べると、フロントエンドはまだまだテストの数が少ないです。
ライブラリのアップデートなどの全体に影響する変更の際に、もっとテストが書かれていればある程度安心してリリースできるのに…ということがありました。 しかし、テストが少ないところからいきなりガッツリとテスト書くことを習慣付けていくのはハードルが高かったりします。
何から始めればコスパ良くテストが厚く書かれている状態に持っていけるかと考え、チーム内でStorybookが活用されていることに着目しました。
Storybookとテスト
STORES 予約 の開発チームでは以下のような形でStorybookを活用しています。 またChromaticを利用しており、PRごとに自動でStorybookがデプロイされるようになっています。
- STORES では Stand と呼ばれるデザインシステムを運用しており、それに則って実装されたコンポーネントであるStandコンポーネントのUIカタログとして
- PRレビュー、またはデザイナーさんとのUIレビューの際に、ChromaticにデプロイされたStorybookで確認してもらう
このように活用されている中でStoryに対してテストを書くことで、以下のメリットがあると感じました。
- propsやmswを利用したAPIのモックはすでにStoryに準備されているため、二度手間にならない
- VRTに関しては、普段通りStoryを書くだけでテスト対象になる
Storybookでテストを行う際はさまざまなアドオンが出ているので、比較的導入はかんたんそうです。
またリグレッションテストについては STORES 予約 でも使用しているChromaticを使用する他にも、Storybookのスクショを撮ってくれるStorycap、その画像の差分をテストしてくれるReg-suitというツールがあります。
今回どんなテストを追加すべきか
フロントエンドのユニットテストとしては、このような方法があります。
またWebアクセシビリティを担保するアクセシビリティテストと呼ばれるものもあるようです。
スナップショットテストについては経験上、クラスなどが変わってもそれがUIとして正しいかを見分けるのが難しく、毎回test -u
を叩いて更新するだけになり形骸化してしまう懸念がありました。
またインタラクションテストは1日で追加できる範囲には限度があるので、長い目でテストを足していく必要があります。
そこでコードクリーニングタイムの1日で何ができるかを考え、VRTを導入することにしました。
VRTのツールの選定
VRT用のツールとしては上でも書きましたが、以下の候補がありました。
- Chromatic
- Storycap + Reg-suit
Chromaticはすでに使用しているためお手軽な選択肢でしたが、規模によってはそれなりの料金になります。 今回は試しに運用してみるというニュアンスもあったので、スクリーンショット保管用のS3の料金程度で済むStorycap + Reg-suitの構成を取りました。
運用してみて
導入方法は公式リポジトリや詳しく書かれている記事があるので割愛します。
導入後にPRをオープンすると、master(main)とのスクリーンショットの差分がレポートと共に飛んでくるようになります。
実際に導入してみて、なかなか難しい点もありました。
何も変更していないのに差分が出てしまうことがある
Storycapはただスクリーンショットを撮るだけなので、場合によって何も変更していないはずでも差分が出てしまうことがあります。
具体的には以下の理由が多かったです。
- cssでアニメーションが設定されていた
- APIをモックするmswのレスポンスの遅延が無限(infinite)になっており、Storycapがいつキャプチャすれば良いか分からずタイムアウトする
- iframeを読み込んでいたので、タイミングによって差分が出た
これらを放置しておくと「どうせ関係ない差分なので見なくても良いか…」となってしまい意味が無くなってしまいます。 どうしても原因を潰せない場合は思い切ってskipし、ノイズを減らしていくことの方が重要だと感じています。
個別の具体的な対処法についてはこちらの記事などを参考にさせていただきました。
CIの実行に時間がかかってしまう
Storyが増えてくると、Storybookのbuildやstorycapの撮影に時間がかかるようになってきます。
Storycapに関してはcli引数に--shard
を渡すことで並列化させることができるので、Story数に合わせて適宜並列で動かすようにしています。
Storybook自体のbuild時間についてはもう少し短くならないかと思ってはいるものの、まだ模索中です。
まとめ
以上、VRTの導入から運用してみてを書いてみました。
まだ導入して日が浅いですが、次にUIに影響するライブラリをアップデートする際などは活躍してくれそうです。 また、今回導入したVRTでは表示についてしかチェックできないため、別途インタラクションテストも拡充し、コンポーネントの動作もテストで担保していく必要がありそうです。
今後VRTを安定化させつつ他の種類のテストも厚くしていくことで、より安心して開発できる環境を作っていきたいと考えています。