画像差分検知ツール「Gazo-san」入門

# 初めに
こんにちは！
株式会社LIFULL SET(Software Engineer in Test)グループの@rueyjyeです。

先日SETグループは日々のVisual Tesingで運用している画像差分検知ツールをOSS化しました。
その名前は[「Gazo-san」](https://github.com/lifull-dev/Gazo-san)です。

今回は実際にGazo-sanを使って、Visual Testingのハンズオンをやってみます！

Visual Testingの紹介とGazo-san検知の仕組みは[LIFULL Creators Blog](https://www.lifull.blog/entry/2019/12/16/110000)に書きました。
興味がある方はぜひ読んでいただければと思います。


# Gazo-sanとは
![logo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/549792d6-ac3b-4ec1-969d-d6f96766c750.png)
弊社のSETはリリース前に、レグレッションテストを実施しています。
E2EテストとVisual Testingの二種類のテストです。

Visual Testingの役割は、リリース前後サイトの「見た目」を比較し、仕様以外の変化や画面崩れなどがあるとかをチェックしています。

一般的な画像差分検知ツールと違いまして、ピクセルごとで比較して差分を検知するではなく、
Gazo-sanは**画像をパーツに分割して、二枚画像の各パーツをマッチングし、マッチングしたパーツのみ差分を検知します。**
マッチングしていないパーツは、消える・増える部分として認識されます。

これによって、パーツがずれる場合でも差分が見やすくなります。

**ピクセルごとに比較するツールの場合:**

| リリース前のサイト|リリース後のサイト|差分|
|:-:|:-:|:-:|
|![test_image_old.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/7f70b1a5-95d6-8e78-0308-e829391cfd99.png)|![test_image_new.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/1f99d5e5-c0f2-eb9b-efff-242c0f6c6d4f.png)|![eee85d76965cf0cc32512b579ff53380.4TxG3V6REgXN5fw4j40e248QmRqoLCyY.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/e8a56644-ca43-bbb3-4d88-99b01ffa84d9.png)|

**Gazo-sanの場合:**

| リリース前のサイト|リリース前のサイト|差分|
|:-:|:-:|:-:|
|![test_image_old.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/7f70b1a5-95d6-8e78-0308-e829391cfd99.png)|![test_image_new.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/1f99d5e5-c0f2-eb9b-efff-242c0f6c6d4f.png)|![70491691-502c5f00-1b45-11ea-9bdc-8cf1f1189593.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/0cb75200-522a-fd1e-48f6-3f65b7b1c98e.png)|

 
# Gazo-sanを使って、Visual Testingを試しましょう
それではGazo-sanを使って、画像差分を検知していきます！

## 撮影
例として、「[tenki.jp](https://tenki.jp/)」サイトの二日分の画像を取ります。
Headless chromeでコマンドラインで撮るか、seleniumで撮るか、撮影方法は自由です。
実際にレグレッションテストで運用する場合、撮影は自動化することがおすすめです。

今回はChromeのデベロッパーツールを使って手動で撮りました。
(Windowsの場合:ctrl+shift+P, Macの場合: command+shift+P、そして「Capture screenshot」を選択 )
<img width="571" alt="スクリーンショット 2019-12-23 9.51.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/d220b349-5d4b-4673-8458-8dfa21d18aea.png">

名前は日付を付けて、保存先は任意の場所で大丈夫です。
このハンズオンはGazo-sanディレクトリに保存します。

|tenki_1220.png|tenki_1221.png|
|:-:|:-:|
|<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/cb2add11-d907-7bca-be1f-1bfdec84b5d4.png">|<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/f6afd9b8-166b-03c4-4f85-6904c49678b0.png">|

## 差分計算
※ Dockerを利用しますので、起動を忘れずにお願いします

最新バージョンのイメージをDocker Hubに上げているので、イメージをPullするだけですぐに利用できます。
実行方法は[Gazo-san READMEのQuick Start](https://github.com/lifull-dev/Gazo-san)と同じ手順です。

```bash
# 画像の保存先に移動
cd Gazo-san

# イメージをローカルにpullする
docker pull lifullsetg/gazo-san

# 差分画像を作成する
# gazosanコマンド後ろのパラメータ順は「新しい画像」、「古い画像」、「出力名」
docker run --rm -it -v `pwd`:/app lifullsetg/gazo-san gazosan tenki_1221.png tenki_1220.png tenki
```

画像のサイズと内容によっては、算出時間がかかるかもしれません。(この例は30秒ぐらいかかると思います)
これを実行したら、名前は「**tenki_diff.png**」の画像が作成されると思います。

## 差分画像の説明
|tenki_diff.png|
|:-:|
|![tenki_diff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/767f5618-a06e-574a-9ec9-75148bf9aa13.png)|

**赤枠：**
赤枠はマッチングした部分です。
tenki_1220.pngとtenki_1221.png両方に存在すると判別したパーツです。
マッチングして、**差分がなければ赤枠のみ囲まれます。**

**赤塗り：**
赤塗りの部分はマッチングしたパーツの差分です。

|マッチングしたパーツ例|
|:-:|
|1220|
|![20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/178a2d25-6153-7c27-5a7d-ad0e156c3a10.png)|
|1221|
|![21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/6a065c16-39f6-f485-1689-9e595350437f.png)
|
|diff|
|![diff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/687182dd-ec86-51a1-7689-03e415b40d45.png)|


## --create-change-image オプションを使う
オプションなしで実行したら、差分画像のみが作成されます。
しかしながら、リリース前後でマッチングしていない状況もよくあると思います。
(例えば、仕様の変更で画面を大幅に変更するなど)

その場合は、差分画像として入力側の画像が使われるので、結果が分かりづらいです。

ここはオプション付けて、もう一回Gazo-sanの差分計算を実行します。

```bash

# 最後で--create-change-imageを付けること
docker run --rm -it -v `pwd`:/app lifullsetg/gazo-san gazosan tenki_1221.png tenki_1220.png tenki --create-change-image
```

「tenkin_diff.png」以外、さらに二枚画像が作成されます。
**「tenkin_delete.png」**と**「tenkin_add.png」**

**「tenkin_delete.png」**はtenki_1220.pngとtenki_1221.pngを比較して、**tenki_1220.pngで消えた部分**が表示されます

|tenki_1220.png|tenkin_delete.png|
|:-:|:-:|
|<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/cb2add11-d907-7bca-be1f-1bfdec84b5d4.png">|<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/b9ee7719-6b1f-3786-2f08-03dcda06f90b.png">|

**「tenkin_add.png」**はtenki_1220.pngとtenki_1221.pngを比較して、**tenki_1221.pngで増えた部分**が表示されます

|tenki_1221.png|tenkin_add.png|
|:-:|:-:|
|<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/f6afd9b8-166b-03c4-4f85-6904c49678b0.png">|<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/b0af3cf1-f559-8688-8d9a-627304fa950f.png">|

**緑枠：**
緑枠はマッチングしていない部分、tenki_1220.pngとtenki_1221.pngの画像にそれぞれ描かれています。
消える部分と増える部分としてそれぞれ認識されます。

|マッチングしていないパーツ例|
|:-:|
|tenki_1220.png 那覇の天気|
|![25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/22410009-4f99-16c7-ef51-f1e62132abda.png)|
|tenki_1221.png 那覇の天気|
|![26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/693ddf01-c82e-eca1-adf5-2454d154d6cc.png)|

※ パーツのマッチングはAIを使わずにパーツ画像を直接比較するので、画像によっては精度がよくない状況があるかもしれません。

# 最後に
三枚の出力画像を並んで、1テストケースとしては完了です！
これで見やすくなり、チェックしやすくなりました。

|tenki_delete.png|tenkin_add.png|tenki_diff.png|
|:-:|:-:|:-:|
|<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/b9ee7719-6b1f-3786-2f08-03dcda06f90b.png">|<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/b0af3cf1-f559-8688-8d9a-627304fa950f.png">|<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/767f5618-a06e-574a-9ec9-75148bf9aa13.png">|

Gazo-sanのコンテナを利用して、素早くVisual Testing実装できると思います。
皆さんもぜひ使ってみてください！！！

[【Github】Gazo-san](https://github.com/lifull-dev/Gazo-san)