8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Cypress + REG CLI ではじめたビジュアルリグレッションテスト

Last updated at Posted at 2021-03-06

WEBアプリケーション検証でビジュアルリグレッションテストの導入を検討しています。
cypress と reg-cli を利用して before/after スクリーンショット比較環境をトライしたときの備忘録です。
導入し易く本格的に活用していきたいと思います。

目次

やること

  • システム改修前後のスクリーンショットを cypress で before/after に保存する
  • reg-cli で before/after 内画像を比較し差分を確認する

cypress環境構築

nodejs,npm インストールは、環境に合わせて実施ください

cypress のインストール

mkdir -p /myproduct
cd /myproduct
npm init -y
npm install cypress --save-dev

cypress 実行コマンドを package.json に追加

package.json
"scripts": {
  "cypress:open": "cypress open",
  "cypress:run": "cypress run"
},

Cypress Test Runner を実行

npm run cypress:open

cypress01.png

Cypress 構成

cypress test runner を実行すると cypress ディレクトリが生成されます。

cypress
  |- fixtures //テストデータを置く
  |- integration //spec ファイルを置く
  |- plugins
  |- support
  |- screenshots //スクリーンショットが保存される
  |- package.json
  |- package-lock.json
  |- cypress.json

# サンプル spec を削除
rm integration/examples

スクリーンショット取得実装

cypress 環境変数の作成

スクリーンショットサイズ・キャプチャモード、ウェイトの環境変数を cypress.json に指定する

cypress.json
{
  "env": {
    "ss_wait_msec": 1000,
    "ss_view_width": 1340,
    "ss_view_height": 1000,
    "ss_capture": "fullPage"
  }
}

スクリーンショットを取得するアクセスリスト(テストデータ)の作成

fixtures/visual-regression-test/pages.json

pages.json
  [
    {
      "test_id": "001",
      "uri": "/001"
    },
    {
      "test_id": "002",
      "uri": "/002"
    },
    {
      "test_id": "003",
      "uri": "/003"
    }
  ]

スクリーンショットを取得する spec ファイルの実装

改修前のスクリーンショット保存
integration/visual-regression-test/before.spec.js
スクリーンショット対象は、テストデータに指定

before.spec.js

describe('before screenshot', function() {
    const pages    = require('../../fixtures/visual-regression-test/pages.json')
    const domain   = 'https://before.com'
    const ss_dir   = 'before'
    var test_id    = ''
    var ss_path    = ''
    var url        = ''

    pages.forEach(({ test_id, uri }) => {
        context(test_id, () => {
            beforeEach(() => {
                url = domain + uri
                cy.visit(url)
            })

            it('take screenshot', function() {
                ss_path = ss_dir + '/' + test_id
                cy.wait(Cypress.env('ss_wait_msec'))
                cy.viewport(Cypress.env('ss_view_width'), Cypress.env('ss_view_height'))
                cy.screenshot(ss_path, {
                    capture: Cypress.env('ss_capture')
                })
            })
        })
    })
})

改修後のスクリーンショット保存
integration/visual-regression-test/after.spec.js
リクエスト先は、before と同じテストデータ pages.json を再利用

after.spec.js

describe('after screenshot', function() {
    const pages    = require('../../fixtures/visual-regression-test/pages.json')
    const domain   = 'https://after.com'
    const ss_dir   = 'after'
    var test_id    = ''
    var ss_path    = ''
    var url        = ''

    pages.forEach(({ test_id, uri }) => {
        context(test_id, () => {
            beforeEach(() => {
                url = domain + uri
                cy.visit(url)
            })

            it('take screenshot', function() {
                ss_path = ss_dir + '/' + test_id
                cy.wait(Cypress.env('ss_wait_msec'))
                cy.viewport(Cypress.env('ss_view_width'), Cypress.env('ss_view_height'))
                cy.screenshot(ss_path, {
                    capture: Cypress.env('ss_capture')
                })
            })
        })
    })
})

スクリーンショット保存先の変更

デフォルトではスクリーンショット保存先が spec.js ファイル毎に別れます

  • screenshots/visual-regression-test/before.spec.js/before/001.png
  • screenshots/visual-regression-test/after.spec.js/after/001.png

reg-cli でbefore/after を指定しやすいパスにしたいので spec.js ファイル名をパスから除く形に plugin で対応

  • screenshots/visual-regression-test/before/001.png
  • screenshots/visual-regression-test/after/001.png

plugins/index.js に追加

index.js
const path = require('path');
const fs = require('fs')

module.exports = (on, config) => {
    on('after:screenshot', (details) => {
        var str = details.path
        var new_path = str.replace(/[a-z-]+\.spec\.js/, '')
        var new_dir  = path.dirname(new_path)
        fs.mkdirSync(new_dir, { recursive: true })
        fs.renameSync(details.path, new_path)
        return { path: new_path }
    })
}

例外発生時にテストが中断されないように対応

デフォルトの動作として例外発生時は、テストが中断されるようです

image.png

テストが中断されないように uncaught exceptions イベントで対応

support/index.js に追加

index.js
Cypress.on('uncaught:exception', (err, runnable) => {
    // returning false here prevents Cypress from
    // failing the test
    return false
})

before/after スクリーンショットを取得する

実装した before/after.spec.js を実行します

image.png

reg-cliの追加インストール

cd ./myproduct
npm install reg-cli --save-dev

スクリーンショット画像を比較

$ reg-cli /path/to/actual-dir /path/to/expected-dir /path/to/diff-dir -R ./report.html

cd ./myproduct
./node_modules/.bin/reg-cli \
  ./cypress/screenshots/visual-regression-test/before \
  ./cypress/screenshots/visual-regression-test/after \
  ./cypress/screenshots/visual-regression-test/diff \
  -R ./cypress/screenshots/visual-regression-test/report/index.html

比較結果が出力されます

✘ change  cypress\screenshots\visual-regression-test\before\001.png
✔ pass    cypress\screenshots\visual-regression-test\before\003.png
✘ change  cypress\screenshots\visual-regression-test\before\002.png


✘ 2 file(s) changed.
✔ 1 file(s) passed.

スクリーンショット差分ファイル

コマンド引数で指定した diff ディレクトリに差分画像が出力される
差分があるスクリーンショットのみ出力されるようです

./cypress/screenshots/visual-regression-test/diff

image.png

スクリーンショット結果レポート

コマンド引数で指定した report ファイルに全ての比較結果が出力されます

./cypress/screenshots/visual-regression-test/report/index.html

比較された画像の結果がわかりやすくリスト表示されます

画像毎の比較結果は、複数の表示モードで確認することができます。

  • Diff
    • 2枚の差分を表示する
  • Slide
    • 画像上でマウスを左右にスライドすることで1枚目(左)、2枚目(右)を表示する
  • 2up
    • 左右に並べて表示する
  • Blend
    • 2枚を重ねて表示する
  • Toggle
    • toggle ボタンで画像を切り替えて表示する

比較精度を調整

-M, --matchingThreshold オプションを指定することで人の見た目に合わせた比較をすることができました(すごい!)

./node_modules/.bin/reg-cli \
  ./cypress/screenshots/visual-regression-test/before \
  ./cypress/screenshots/visual-regression-test/after \
  ./cypress/screenshots/visual-regression-test/diff \
  -R ./cypress/screenshots/visual-regression-test/report/index.html
  -M 0.2

-M 0.2 0 - 1 の範囲を指定できるようで、小数点指定してみました。

参考にさせていただいたページ

https://qiita.com/natsu_mikan/items/692018262b617bb87859
https://qiita.com/hurikake06/items/9930a9ad223e86320c8f
https://www.cypress.io/
https://github.com/reg-viz/reg-cli

8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?