reg-suitでVisual Regression Testしてみた


**注意：reg-suitの概要は把握している前提で執筆する**

# 目的

- reg-suitでビジュアルリグレッションテストしてみてざっくり導入出来そうか検討する

# 前提条件
- 今回はHTML&CSSからスクショして簡単な画像比較を行う
    - [参考にしたreg-suitの公式リポジトリ](https://github.com/reg-viz/reg-puppeteer-demo)

|  ソフト  |  バージョン  |
| ---- | ---- |
|  OS  |  macOS Catalina  |
|  Chrome  |  83.0.4103.116  |


# 使ったツール

- GitHub
- AWS
- CircleCI

# 作業ログ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528657/d5752fba-59a0-5706-81f5-15a63f1f05e8.png)



- cloneしてきたリポジトリ
    - [https://github.com/reg-viz/reg-puppeteer-demo](https://github.com/reg-viz/reg-puppeteer-demo)
    - こちらのReadmeを参考にreg-suit使ってみる


- 自分でテストしたリポジトリ
    - [https://github.com/takahigu322/reg-suit-demo2](https://github.com/takahigu322/reg-suit-demo2)
    

## 1. project作成

1. はじめに project directoryを作成.

```jsx
mkdir reg-puppeteer-demo
cd reg-puppeteer-demo
// ここにclone
git init
npm init
```

## 2. HTML と CSS作成

1. サンプルのHTMLとスタイルを配置します。 reg-suitを使用してこのHTMLをテストします。
2. `yarn add semantic-ui-css` でcss適用←公式リポジトリのReadmeにないので注意


## 3. スクリーンショットをキャプチャするためのスクリプトを作成する

index.htmlのスクリーンショット画像を視覚回帰テストのreg-suitに提供する必要があります。そこで、ヘッドレスChromeのNode.jsプログラマブルインターフェイスであり、スクリーンショットAPIを提供するPuppeteerをインストールします。

1. `npm install -D puppeteer mkdirp` 
2. 次のスクリプトを使用すると、HTMLファイルをキャプチャできます。

    ```capture.js
    const puppeteer = require('puppeteer');
    const mkdirp = require('mkdirp');

    async function main() {
      const browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] });
      let page = await browser.newPage();

      await page.setViewport({ width: 640, height: 680 });
      await page.goto(`file://${__dirname}/index.html`);
      await new Promise(res => setTimeout(() => res(), 300));
      await page.screenshot({ path: 'screenshot/index.png' });

      await page.close();
      await browser.close();
    }

    mkdirp.sync('screenshot');
    main();
    ```

    2. `node capture.js` でスクショ→`screenshot/index.png`を開く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528657/d197920d-05c4-6d09-60d2-7915412d86fd.png)



## 4. AWS credentialsを準備

```
export AWS_ACCESS_KEY_ID=<your-access-key>
export AWS_SECRET_ACCESS_KEY=<your-secret-key>
```

## 5. reg-suitを構成する

1. `npm install -D reg-suit`でreg-suitをインストール
2. `npx reg-suit init`　or `reg-suit init` 
    1. インストールするプラグインを尋ねます。今回は以下の4つ
        1. reg-keygen-git-hash-plugin
        2. reg-notify-github-plugin
        3. reg-publish-s3-plugin
        4. reg-notify-slack-plugin
    2. 「作業ディレクトリ」と「しきい値」で「はい」を渡します。 「ディレクトリに実際の画像が含まれています」という質問では、上記の手順で準備したスクリーンショットディレクトリを指定する必要があります。

        ```jsx
        ? Working directory of reg-suit. .reg
        ? Directory contains actual images. screenshot
        ? Threshold, ranges from 0 to 1. Smaller value makes the comparison more sensitive. 0
        ```

    3. S3バケットの場所を指定します

        ```jsx
        [reg-suit] info version: 0.8.6
        [reg-suit] info Set up reg-publish-s3-plugin:
        ? reg-publish-s3-plugin has been already configured. Override this configuration Yes
        ? Create a new S3 bucket Yes
        [reg-publish-s3-plugin] info Create new S3 bucket
        ```

    4. githubのclientID
        - リポジトリのClientIDを聞かれるので予め作っておく
    5. slackのwebhookURL
        - webhookURLを設定したらtest messageが飛んできた


    6. 最後に、設定を確認します。したがって、設定ファイルはregconfig.jsonに作成されます。


        ```jsx
        [reg-suit] info Configuration:
        [reg-suit] info {...}
        ? Update configuration file Yes
        ? Copy sample images to working dir No
        [reg-suit] info Initialization ended successfully ✨
        ```


    7. 変更をcommitして `npx reg-suit run` or `reg-suit run`

        ```jsx
        commit c8f99eb1a5c6abb64d67d9277d29b71bbf18c986 (origin/master, origin/HEAD, master)
        Author: takahigu322 <takahigu642@gmail.com>
        Date:   Fri Jun 19 11:56:21 2020 +0900

            first commit
        ```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528657/f0550f95-ef21-edc9-6ad5-e6f4568c40c5.png)


       

## 6. Create build script for CircleCI
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528657/adcb5158-4383-d8d1-8ab0-653d8cd4b6f0.png)




Project Setting → Organization Settings → Contexts　にAWS認証情報を追加

## 7. 通知を構成する

この機能をオンにするには、`reg-notify-github-plugin`をインストールします。

```jsx
npm install -D reg-notify-github-plugin
```

Antは、次のコマンドを使用してこのプラグインを構成します。

もし`5.reg-suitを構成する`でプラグインを選んでたらスルー

```jsx
npx reg-suit prepare --plugin notify-github
```

## 8. レポートをプレビュー

新しいブランチを作成します。

```jsx
git checkout -b add-avatar2
```

`index.html` fileを書き換える
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528657/a0a6f856-9a43-f6fa-b9c1-d1cfa50aa7b9.png)


GitHubリポジトリでプルリクエストをコミット、プッシュ、add-avatar2からmasterへプルリクオープンします。

`reg-suit bot`が出るまで10分少々かかった

`reg-suit run`　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528657/b18212ec-27fc-a133-cc91-9a9305252aaa.png)


`this report`クリック
↓が結果
[Comparison Report - REG](https://reg-publish-bucket-dd260a8b-8b50-4dc6-bdca-79e041ef77f1.s3.amazonaws.com/30f505df8dfb6c292965b6d417867f8090e7c87c/index.html)

# 導入検討

reg-suit使ってみた感想
導入することによるメリデメ

- 正しく検出しないと誤解を招く
- 改修した部分を確認は出来る
- ビジュアルリグレッションテストとしては足りない所がある
- 前回と比べて変わった所を把握した上で判断した
- **意図せず変わった所を検出できるのは良い**
- 何か必要？
- 差が出てるだけ
    - これを誰かが判断しないと、この結果を受けて。これを自動でできるのかが分からない
- 正しい使用方法との認識のズレがある可能性もある
- 開発者が変化に気付ける
- reg-suitは1px単位のズレを検出
- 運用としては軽い
- テストとは言えない、ただの通知でしかない
- 今回はHTMLで比較
- 今回のをきっかけに付随するものを検出
- **capture.jsで複数画面を取得する→すごい手間になる**
- 前回と今回の比較になる
- 境界値的なものを把握した前提
- storybookにカタログを使う
- そもそもどこからこのテストを導入することに
    - ECサイトのリグレッションテスト
    - うちで言う動画700種類、footerの内容で使える
- Misocaは日毎にやってて良さそう
    - Capybaraのスクリーンショット
- RRRSpecで分散実行
- 全部Vueに実行
- CIじゃなくてよくね？
- 定期的に実行される→自動化したい
- component単位で確認したい→reg-suit出来るの？
    - reg-suitは単純な画像比較

# 参考資料

[Misocaにおけるビジュアルテストへの取り組み](https://slides.com/kokuyouwind/railsdm2019#/36)

[1px の変化も見逃さない！ビジュアルリグレッションテスト導入で快適フロントエンド開発 - クラシル開発ブログ](https://tech.dely.jp/entry/vis_reg_test)

[Percy + CypressでVisual Regression Test - kenfdev's blog](https://kenfdev.hateblo.jp/entry/2019/08/25/121740)