🧪

VRTの改善のために実施したこと

2023/07/20に公開

こんにちは。アルダグラムでエンジニアをしている松田です。

弊社のフロントエンド開発では、品質担保施策の一環としてVRTを実施しています。
最近、VRTについていくつかの改善を施しましたので、本稿ではその施策例を紹介します。

VRT (Visual Regression Testing) とは?

UIを実際にブラウザで描画した際に、更新前後で描画内容の差分を検知し、見かけ上の変更差分を知ることができる、といったものです。

https://storybook.js.org/docs/react/writing-tests/visual-testing

弊社のプロダクト開発では、reg-suitstorycap を用いて、Storybookを対象にVRTを実施しています。

https://github.com/reg-viz/reg-suit

https://github.com/reg-viz/storycap

改善対象

regconfig.json

reg-suit の設定ファイルです。
Storyの差分判定を適切に緩和するため、以下の値を調整しました。

  • thresholdRate
    • 差分比率の許容値
    • 差分ピクセル数 / 総ピクセル数
    • 閾値超過時に Changed となる
  • matchingThreshold
    • 色のムラ (YUV色空間での差分) の許容値

なお、これらの値は比率であるため、storyのページの大きさによって許容量が変動します。

https://github.com/reg-viz/reg-suit#core

parameters

Storybookのpreview.jsで設定した parameters は、Storyごとに上書きすることができます。
例えば、特定のStoryのみスクリーンショットの実行を遅らせたい場合は、以下のようにdelayを付与できます。

import { ComponentMeta, ComponentStory } from '@storybook/react'
import Page from 'path/to/sample'

export default {
  title: 'path/to/sample',
  component: Page
} as ComponentMeta<typeof Page>

const Template: ComponentStory<typeof Page> = args => <Page {...args} />

export const Sample = Template.bind({})

// parametersでstorycapのdelayを設定する
Sample.parameters = {
  screenshot: { delay: 6000 }
}

https://storybook.js.org/docs/react/writing-stories/parameters

decorator

decoratorについては追加で付与することができます。
play function実行前などに、特定の処理を施しておきたい時に便利です。
以下は、localStorageに値を追加する例です。

export const Sample = Template.bind({})
Sample.decorators = [
  (Story, context) => {
    window.localStorage.setItem('storageKey', 'value')
    return Story(context)
  }
]

頻繁に用いるdecoratorは別途ファイルでexportしておいて、importする体で利用するのもよいでしょう。

https://storybook.js.org/docs/react/writing-stories/decorators#story-decorators

play function

要素取得の際のQuery

基本的には、 getby… 系ではなく findby… 系を用いた方がよいでしょう。
findby… 系は対象要素のレンダリングを待機しますが、getby… 系は待機しないからです。

https://testing-library.com/docs/queries/about/

unhover

hover時に動的にスタイル変更が生じる場合、キャプチャのタイミングによって差分が生じることがあります。

運用上、不要な差分検知である場合は、unhoverを用いることで、hoverイベントを終了させることで回避できます。

https://testing-library.com/docs/ecosystem-user-event/#unhoverelement-options

SVGのclipPath

SVGにはclipPathという要素を用いて、切り抜きやマスクといった描画効果を使用することができます。

https://developer.mozilla.org/ja/docs/Web/SVG/Element/clipPath

ただ、clipPathのid属性の重複があると、干渉を引き起こし、想定された描画処理が為されない場合があります。

具体的には、SVG内部でurl() によって、マスキング用の要素が内部参照が実施されていることがありますが、id重複があると参照が上手くいかないことがあります。

https://developer.mozilla.org/ja/docs/Web/CSS/url

SVGを集積したアイコンカタログのStoryにおいて、この問題が生じていました。
SVG内の clipPath のid属性に固有の値を設けることで、この問題を解決することができました。
Adobe Illustratorなどで作成されるSVGのclipPathでは、1,2,3,… や a,b,c,… といった単純な連番がidとして振られる可能性があるので、注意してください。

逆説的には、アイコンカタログのStoryを設けておくと、clipPathの重複を事前に検知可能となるでしょう

まとめ

以上のように、VRT安定化のためには様々な手段を講じられます。

不安定なテストは狼少年のようになってしまう恐れがあるため、可能な限り検知精度を高めていきたいところです。


もっと、アルダグラムのエンジニア組織について知りたい人は、下記の情報欄をチェック!

アルダグラム Tech Blog

Discussion