Slide 1

Slide 1 text

Misocaにおける ビジュアルテストへの 取り組み 株式会社Misoca 森 俊介

Slide 2

Slide 2 text

$ whoami 森 俊介 / 黒曜 @kokuyouwind 株式会社Misoca 一応Railsエンジニア 最近はTerraformとかDockerを よく触っている

Slide 3

Slide 3 text

突然ですが

Slide 4

Slide 4 text

自動テスト してるよって人 🙋

Slide 5

Slide 5 text

E2Eの自動テスト してるよって人 🙋

Slide 6

Slide 6 text

デザインの自動テスト してるよって人 🙋

Slide 7

Slide 7 text

CSSの問題検知は難しい 🤔 marginすこし弄ったけど、 使ってるところは確認したし CI Greenだから大丈夫だよね……

Slide 8

Slide 8 text

結果……

Slide 9

Slide 9 text

真ん中に出るはずのモーダルが 下にずれた この下にあるボタンが 押せなくなってる 😢

Slide 10

Slide 10 text

_⼈⼈⼈⼈⼈⼈_ > 突然の死 <  ̄Y^Y^Y^Y^Y^Y^  ̄

Slide 11

Slide 11 text

なぜ気づけないか? feature specではDOM構造を検査する デザイン崩れはほぼ検知できない 影響範囲がグローバル classの命名規約が適切でないと、 どこに影響するかがわからない grepで見つけられるかというと…… div.container li > a とか……

Slide 12

Slide 12 text

そこでビジュアルテストですよ!

Slide 13

Slide 13 text

ビジュアルテストって? ビジュアルリグレッションテスト (Visual Regression Testing)が正確 「見た目」に対するテスト キャプチャ画像などのdiffを検査する

Slide 14

Slide 14 text

ビジュアルテストのレポート

Slide 15

Slide 15 text

Agenda ビジュアルテストの概要 Misocaでの活用事例の紹介 運用での工夫や注意点 今後の展望・活用アイディア まとめ

Slide 16

Slide 16 text

Agenda ビジュアルテストの概要 Misocaでの活用事例の紹介 運用での工夫や注意点 今後の展望・活用アイディア まとめ

Slide 17

Slide 17 text

ビジュアルテストの流れ 1. 現在の外観をキャプチャ 2. 正答画像の取得 3. 画像の比較・レポート

Slide 18

Slide 18 text

各ステップごとに いくつかのやり方がある

Slide 19

Slide 19 text

ビジュアルテストの流れ 1. 現在の外観をキャプチャ 2. 正答画像の取得 3. 画像の比較・レポート

Slide 20

Slide 20 text

手法分類ー外観キャプチャ テストしたい単位で描画 コンポーネント単位など 一時サーバでキャプチャ Feature SpecでのRackサーバなど 実環境でキャプチャ

Slide 21

Slide 21 text

テストしたい単位で描画 Pros. コンポーネント単位で差分が出せる データを自由に変えやすい サーバアクセス不要なので早い(はず) Cons. 実際の画面単位の描画とは多少差がある RailsのPartial Viewでは工夫が必要

Slide 22

Slide 22 text

一時サーバでキャプチャ Pros. 既存のE2Eテストに組み込める(かもしれない) データを自由に変えやすい 実際の画面単位でキャプチャできる Cons. 必要な単位での描画と比べると重い ランダム要素があると、E2Eテストと同居できない

Slide 23

Slide 23 text

実環境でキャプチャ Pros. 導入しやすい 簡単にページを開いて確認できる Cons. 実アプリ上でデータの準備・保守が必要 時間経過などで見た目が変わると使えない 表示が恒常的に変わる操作はテストできない

Slide 24

Slide 24 text

ビジュアルテストの流れ 1. 現在の外観をキャプチャ 2. 正答画像の取得 3. 画像の比較・レポート

Slide 25

Slide 25 text

手法分類ー正答画像の取得 正答画像を別途保存 人間が都度判断して更新する 前回のキャプチャと比較 分岐元のキャプチャと比較 gitのコミットごとに画像を貯めておく git branchが分岐した元の画像と比較する

Slide 26

Slide 26 text

正答画像を別途保存 Pros. 正答データと確実に比較できる Cons. 正答データが変わると更新が必要

Slide 27

Slide 27 text

前回のキャプチャと比較 Pros. 自動で正答データが最新になる Cons. 一度差分を見逃すと、次回以降検知できない 検知した差分を修正したときも差分が出る

Slide 28

Slide 28 text

分岐元のキャプチャと比較 Pros. PR単位でmasterからの差分を確認できる 自動で正答データが更新される Cons. 運用環境でのテストでは使えない Gitの分岐元判定が難しい

Slide 29

Slide 29 text

ビジュアルテストの流れ 1. 現在の外観をキャプチャ 2. 正答画像の取得 3. 画像の比較・レポート

Slide 30

Slide 30 text

画像の比較・レポート ここは大差ない 画像diffツールに何が使われるかくらい レポートは大抵HTMLで出てくる 誤差許容パラメタのほうが重要 差分をどの程度許容するか(px/%) 色の違いをどの程度まで一致とみなすか

Slide 31

Slide 31 text

どれがいいの? それぞれ向き・不向きがある 運用環境でリリース毎や定期的に見るのか PR単位でmasterからの差分を見るのか ツールによって担当範囲や手法が違う

Slide 32

Slide 32 text

ビジュアルテストツール reg-suit 正答データ管理や通知をカスタマイズできる 現在の外観画像は別途用意が必要 BackstopJS 外観画像取得から比較まで全部やってくれる 実環境へのWebアクセス+正答データ明示のみ Storybook コンポーネント単位でレンダリング

Slide 33

Slide 33 text

目的に応じて適切な方法を 組み合わせる必要がある

Slide 34

Slide 34 text

Agenda ビジュアルテスト手法の分類 Misocaでの活用事例の紹介 運用での工夫や注意点 今後の展望・活用アイディア まとめ

Slide 35

Slide 35 text

Misocaでのビジュアルテスト 本番環境・ステージ環境のキャプチャ 実環境で前回との差分チェック ローカル環境のキャプチャ 実環境で正答データとの差分チェック 帳票PDFのキャプチャ PDFを描画し、正答データとの差分チェック

Slide 36

Slide 36 text

本番環境 日次で、前日との差分を検知 キャプチャ: capybara-screenshot 正答管理: reg-suit simple-keygen(Jenkinsビルド番号をキー) 差分レポート: reg-suit Slackの専用チャンネルに通知 差分があったら、問題ないかを見てスレッドに書く

Slide 37

Slide 37 text

Slack通知

Slide 38

Slide 38 text

reg-suitのレポート画面(再掲)

Slide 39

Slide 39 text

ステージ環境 リリース毎に、前回との差分を検知 本番環境と同じ仕組み キャプチャ: capybara-screenshot 正答管理: reg-suit simple-keygen(Jenkinsビルド番号をキー) 差分レポート: reg-suit リリース作業チャンネルに通知 差分があったら、問題ないかを見てスレッドに書く

Slide 40

Slide 40 text

Slack通知

Slide 41

Slide 41 text

ローカル環境 必要なときに手動で実行 キャプチャ: BackstopJS 正答管理: BackstopJS(init, approve) 差分レポート: BackstopJS

Slide 42

Slide 42 text

なぜ本番・ステージと違う? ローカルで表示しづらい画面がある 外部連携など 環境によって描画に微妙な差が出る 正答データが集約できない Dockerを使えば解決しそう CSSを書く人がJavaScriptに慣れていた

Slide 43

Slide 43 text

帳票PDF 通常CIで、正答データとの差分を検知 キャプチャ: MiniMagickでpdf -> pngに変換 正答管理: Gitコミット(approveモード実行で上書き) 差分レポート: MiniMagick 失敗した場合はPR Statusに反映 他のテストが失敗したときと同じ

Slide 44

Slide 44 text

帳票PDFのdiff

Slide 45

Slide 45 text

なぜ帳票だけ? Misocaのサービス上重要な部分 個別に整備する価値がある 現在手を入れている箇所なので、安心して触りたい PDF生成処理が独立している データを変えて網羅的にテストしやすい

Slide 46

Slide 46 text

環境に応じて色々やってる ステージ環境が防衛ライン 最悪でも本番で日次検知

Slide 47

Slide 47 text

Agenda ビジュアルテスト手法の分類 Misocaでの活用事例の紹介 運用での工夫や注意点 今後の展望・活用アイディア まとめ

Slide 48

Slide 48 text

キャプチャ時の注意点 CSSでアニメーションやキャレットを切る 非同期読み込みは少し長めに待つ 画像も長めに待たないと出ない事がある 画面や状態がわかる画像名にする 「請求書編集画面-プルダウン-発行.png」など ルールを作ってヘルパーメソッドを作ると良い

Slide 49

Slide 49 text

CSSでアニメーションを切る def disable_animations page.execute_script(ANIMATIONS_DESABLE_SCRIPT) end ANIMATIONS_DISABLE_STYLE = <<~CSS CSS ANIMATIONS_DESABLE_SCRIPT = <<~"SCRIPT" const style = document.createElement('style'); style.innerHTML = `#{ANIMATIONS_DISABLE_STYLE}`; document.head.appendChild(style); SCRIPT

Slide 50

Slide 50 text

テストコード module Pages module Invoices include Pages::Base register_tours do tour ' 請求書⼀覧画⾯', '/invoices' do screenshot full: true check 'order[invoices][]', match: :first screenshot ' フッター- 単独', full: true check 'all-checkbox' screenshot ' フッター- 複数', full: true uncheck 'all-checkbox' # ...

Slide 51

Slide 51 text

テストコード 基本はただのCapybaraコード ヘルパーメソッドをいくつか作っている tour(view_name, path) pathにvisitする screenshot(state_name, full: bool, sleep: oat) 現在の画面を(view_name + state_name)で保存する fullなら縦幅を要素に合わせる 画面キャプチャ前にsleep秒待つ

Slide 52

Slide 52 text

キャプチャするメソッド def screenshot(name = nil, wait: 0.5, full: false) # テキストボックスのキャレットが表示されないようにする page.execute_script "document.activeElement.style.caretColor = 'transparent'" # ページの読み込み待ちと負荷軽減を兼ねて、少し待つ sleep(wait) # 全体をスクリーンショットに撮るために、ブラウザウィンドウをリサイズする resize_to_full if full Capybara::Screenshot.new_saver(Capybara, Capybara.page, false, name ? "#{pagename}_#{name}" # ブラウザウィンドをリサイズしていた場合、元に戻す resize_to_default if full end

Slide 53

Slide 53 text

どの程度網羅するか コーナーケースを追求しすぎない 1ケースごとに実行がかなり遅くなる 実環境に対しては分散実行も負荷・競合リスクになる 重要 / 典型的なケースをテストする 1画面で複数の状態をテストする 一覧画面では複数項目でパターン網羅できる

Slide 54

Slide 54 text

一覧画面の例

Slide 55

Slide 55 text

誤差の許容 どの程度、画像の誤差を許容するか 小さすぎると誤検知が増える(False Positive) 大きすぎると差異を見逃す(False Negative) False Positiveが多すぎるとつらい ブラウザレンダリングで数pxのdiffが出たりする

Slide 56

Slide 56 text

微妙な誤差

Slide 57

Slide 57 text

誤差許容の設定 // regconfig.json { "core": { "workingDir": ".reg", "actualDir": "screenshots", "thresholdPixel": 50, "addIgnore": true, "thresholdRate": 0, "ximgdiff": { "invocationType": "client" } }, // ... }

Slide 58

Slide 58 text

差分検知時の対応 本番/ステージでは意図通りのdiffが出る お知らせの更新など、本番のデータ変更 実際のデザイン変更 Slackに通知してチェックする スレッドがついてなければまだ誰も見ていない 差分検知時に確認する体制 / フローが重要

Slide 59

Slide 59 text

Slack通知(再掲)

Slide 60

Slide 60 text

Agenda ビジュアルテスト手法の分類 Misocaでの活用事例の紹介 運用での工夫や注意点 今後の展望・活用アイディア まとめ

Slide 61

Slide 61 text

PRごとのビジュアルテスト 表示に使うデータを揃える必要がある created_atなども表示するなら揃える必要がある 既存のfeature specとは別にしたほうが扱いやすそう rrrspecで分散実行している 画像を集約する必要がある S3に吐いておけば良さそう

Slide 62

Slide 62 text

コンポーネント単位のテスト 全部Vue.js化すればできる…… そう簡単にはできない partial単位で画像を作れないか 必要なCSSだけ読み込めるように分ける コンポーネントカタログ的なページをRailsでレンダリング ページ全体をrenderしてから必要な要素以外をdisplay: hiddenにする

Slide 63

Slide 63 text

Agenda ビジュアルテスト手法の分類 Misocaでの活用事例の紹介 運用での工夫や注意点 今後の展望・活用アイディア まとめ

Slide 64

Slide 64 text

結局導入してよかった? よかった リファクタで意図しないマージンにリリース前時点で気づけた 「意図通りにデザインが変わる」ことを確認できるのも安心できる 仕組みを作れば、保守コストは割と安い DOM構造が変わってもほとんど直さずに動く CIにかかる時間は増えるので、うまく妥協する

Slide 65

Slide 65 text

まとめ ビジュアルテストにもいろいろある 運用環境での差分検査が導入しやすい 重要な部分に絞って網羅的に検査するのもあり 普通のテストと違う運用が必要 False PositiveとFalse Negativeのバランスを取る 検知した差分が意図どおりか確認する体制・フロー