こんにちは!
LIFULLのSETグループ (Software Engineer in Testグループ)のRueyです。
前回はE2Eテストで使うテストフレームワーク「Bucky」を公開しました!
そして今回はVisual Testingで使う画像差分検知ツール「Gazo-san」を公開しました!
この記事はVisual Testingと「Gazo-san」のポイントを紹介したいと思います。
目次
Visual Testingについて
Visual Testingは皆様も時々耳にすることがあると思います。
ですが、 私が調べた限りでは正式な定義がないようです。
※ 日本語訳もないので、本記事は全部Visual Testingと表現します。
あるVisual Testingツールのサイトを参照すると、
「Visual testing is how you ensure that your app appears to the user as you intended.」と書かれています。
つまり、Visual Testingはウェブアプリの「見た目」がユーザーにとって望ましい状態であることを保証するテストです。
参照元:https://applitools.com/blog/visual-testing?nab=4
なぜVisual Testingが必要か
フロントエンドの開発だと、htmlやcssやjavascriptなどの組合せによりサイトの見た目がしばしば変更されます。
「見た目」に影響する要因が多いので、実装後の表示が望ましくない変化(例えば、文字化けや表示崩れなど)、たまにコード上と自分の開発環境では気づかない状況があります。
その際に直接ユーザーと同じ環境でアプリを開いて、目視で確認したほうが安心だと思います。
Visual Testingツールの三要素
でも目視で確認すると、大変ではないですか?😇
実装前後のサイトキャプチャーを取らないといけない。。。
サイトのフルサイズキャプチャーが長いので見辛い。。。
モバイルデバイスと同じ画面を確認しないといけない。。。
細かい差分を目で認識し辛い。。。
数十、数百個のケースを確認すると目が疲れる。。。
いろんな問題点がありますが、良いツールがあれば解消出来そうです。
上記の問題点をまとめると、次の三要素を満たす機能があれば楽にテストできると思います。
- 撮影機能
- 差分検知機能
- レポート機能
撮影機能 📷
キャプチャーがないと見た目の差分が比較出来ないです。
しかし、レグレッションテストなので、実装前後のタイミングで撮影することが重要です。
ユーザーと同じ見た目で確認したいので、キャプチャーのサイズと特定のモバイル端末の指定も重要です。
差分検知機能 🔍
実装前後のキャプチャーの差分を検知する部分です。
これにより、チェックが必要な部分と必要でない部分が切り分けられるので、確認の工数を削減できると思います。
下図はGazo-sanで差分を検知する例です:
赤い部分は差分がある部分、それ以外は差分がない部分です。確認する時は、赤い部分のみチェックするだけで良いです。
レポート機能 📑
数十、数百の差分画像を確認するのも大変なので、レポート形式だと見やすく、確認の工数も削減できると思います。
テストケースの管理と明確なトレーサビリティも重要なので、ダッシュボードで管理できれば分析も楽になると思います。
E2Eテストとの違い
開発前後の「見た目」の変化を確認するテストなので、レグレッションテストにも含まれます。
同じレグレッションテストによく使われているE2Eテストと比べて、それぞれ保証できる部分は少し違います。
E2EテストはUIの操作を行って、アプリの機能が正しく動作することを保証するテストです。
E2Eテストは動作の保証、Visual Testingは見た目の保証
E2EテストではUIを操作する時にclassやidなどの属性で要素を指定して操作を行います。
その際に、例えば操作対象の要素が違う場所に変わっても、操作が問題なく実行できることが多いです。
つまり表示崩れなどがあった場合、検知できない可能性があります。
そこで、アプリの「見た目」の変化を保証するために、Visual Testingを組みあわせて使うのが効果的だと思います。
Visual Testingはメンテナンス不要
ページの要素を操作するE2Eテストはアプリケーションの変更内容に合わせてテストコードを修正する必要があります。
Visual Testingはキャプチャーを撮って比較するだけなので、変更に合わせてのメンテナンスはありません。
ただし、アプリケーションのデータ不備の対応やテスト対象の見直しなどは発生します。
LIFULL SETグループのVisual Testing
SETグループがVisual Testingを行う理由は下記の二つです。
- 見た目の変化を保証するため
- E2Eテストと組合せてより大きな範囲をカバーするため
E2Eテストは実装するための工数がかかりますが、Visual Testingは確認したいページのキャプチャーがあれば実行が可能です。
E2Eテストで確認や実装がし辛い部分をVisual Testingで担保する作戦です。
SETグループは既成のVisual Testingツールを導入しておらず、先ほどの三要素をそれぞれ対応してVisual Testingを実現しています。
撮影部分
Headless Chromeを利用して、サイトのキャプチャーを撮っています。
差分検知部分
今回OSSとして公開した「Gazo-san」を利用して、差分画像を作成しています。
詳しい説明はGazo-san差分検知の仕組みで説明します。
レポート部分
静的サイトのテンプレートを用意し、各ケースの差分詳細ページを作っています。
チェックが必要なケースを見やすくしています。
詳細ページの例:
以上の組合せでリリース前にレポートが自動で生成され、確認が必要な画像差分とその該当ページのチェックを行います。
差分は開発の仕様通りならテストパス、明らかにおかしい場合は該当開発チームに連絡するようにしています。
SETグループのVisual Testingは統合環境で行われており、各開発チームの実装が互いに影響がないかを確認することで、システムテストレベルでアプリ全体の「見た目」を担保しています。
まだまだ改善点があると思いますが、運用自体は問題なく、毎日10分間で150ケースぐらい確認できています。
Gazo-san差分検知の仕組み
Gazo-sanの仕組みを紹介する前に、画像差分の検知方法について紹介します。
画像の差分検知の仕組みは大きく分けると、二種類あると思います。
- 厳密な比較:ピクセルごとの比較 (Pixel perfect testing とも呼ばれます)
- 曖昧な比較:アルゴリズムによる類似度での比較 (類似度算出のアルゴリズムは色々あります)
厳密な比較は差分を画像上で色を付けてアウトプットすることが多いです。
曖昧な比較は差分は表示されませんが、類似度がアウトプットになります。(True/Falseもしくは %)
厳密な比較 | 曖昧な比較 | |
---|---|---|
メリット | 差分を細かく検知できる | 1. サイズ違う画像も検知できる 2. 差分が多い場合に影響がない |
デメリット | 1. サイズが違う画像に弱い (差分の箇所が分かりづらい) 2. 差分が多すぎると見辛くなる (赤く塗られた部分が目立つ) |
差分を細かく表示することができない |
Gazo-sanのポイント
Gazo-sanは厳密な比較に当てはまりますが、差分の表示箇所が分かり辛い問題に対応するため、特殊な仕組みを使っています。
それは二つの画像をそれぞれパーツごと分けて、マッチングしたパーツのみ差分を比較することです。
デモ画像を用いて説明します。
パーツごとの差分検知について
1. 比較する画像入力
変更前 | 変更後 |
---|---|
2. それぞれパーツ画像を作成
変更前 | 変更後 |
---|---|
3. パーツマッチングと差分検知
マッチングし、差分がない |
---|
マッチングし、差分がある |
---|
マッチングしない |
---|
4. Output画像作成
diff画像はマッチングしたパーツを赤枠で囲み、差分がある部分を赤く塗りつぶしています。
Output_diff |
---|
delete画像は修正後の画像と比較して、消えたパーツを緑枠で囲んでいます。
Output_delete |
---|
add画像は修正前の画像と比較して、追加されたパーツを緑枠で囲んでいます。
Output_add |
---|
このパーツ分けの仕組みによって、サイズが多少ずれても差分表示が見やすくなります。
最後に
LIFULLのSETグループはリリース前にVisual Testingを行い、見た目がユーザーにとって望ましい状態であることを保証しています。
「見た目」のデグレを発見した実績も何回かありますので、Visual Testingがあった方が安心だと思っています。
Gazo-sanを使えば簡単にVisual Testingが出来ます。
皆さんも是非お試しください。
また、Gazo-sanの他にもVisual Testing専門のツールは沢山あります。
自分のチームに合うツールを選択して使ってみるのが良いかと思います。
Gazo-sanも改善できるところはまだまだあると思っているので、issue、PullRequestもお待ちしてます。
皆さんも楽しくVisual Testingをやっていきましょう!