株式会社Misoca
森 俊介
森 俊介 / 黒曜
@kokuyouwind
株式会社Misoca
一応Railsエンジニア
最近はTerraformとかDockerをよく触っている
🤔
marginすこし弄ったけど、
使ってるところは確認したし
CI Greenだから大丈夫だよね……
真ん中に出るはずのモーダルが
下にずれた
この下にあるボタンが
押せなくなってる😢
_人人人人人人_ > 突然の死 <  ̄Y^Y^Y^Y^Y^Y^ ̄
feature specではDOM構造を検査する
デザイン崩れはほぼ検知できない
影響範囲がグローバル
classの命名規約が適切でないと、
どこに影響するかがわからない
grepで見つけられるかというと……
div.container li > a とか……
ビジュアルリグレッションテスト
(Visual Regression Testing)が正確
「見た目」に対するテスト
キャプチャ画像などのdiffを検査する
ビジュアルテストの概要
Misocaでの活用事例の紹介
運用での工夫や注意点
今後の展望・活用アイディア
まとめ
ビジュアルテストの概要
Misocaでの活用事例の紹介
運用での工夫や注意点
今後の展望・活用アイディア
まとめ
1. 現在の外観をキャプチャ
2. 正答画像の取得
3. 画像の比較・レポート
1. 現在の外観をキャプチャ
2. 正答画像の取得
3. 画像の比較・レポート
テストしたい単位で描画
コンポーネント単位など
一時サーバでキャプチャ
Feature SpecでのRackサーバなど
実環境でキャプチャ
Pros.
コンポーネント単位で差分が出せる
データを自由に変えやすい
サーバアクセス不要なので早い(はず)
Cons.
実際の画面単位の描画とは多少差がある
RailsのPartial Viewでは工夫が必要
Pros.
既存のE2Eテストに組み込める(かもしれない)
データを自由に変えやすい
実際の画面単位でキャプチャできる
Cons.
必要な単位での描画と比べると重い
ランダム要素があると、E2Eテストと同居できない
Pros.
導入しやすい
簡単にページを開いて確認できる
Cons.
実アプリ上でデータの準備・保守が必要
時間経過などで見た目が変わると使えない
表示が恒常的に変わる操作はテストできない
1. 現在の外観をキャプチャ
2. 正答画像の取得
3. 画像の比較・レポート
正答画像を別途保存
人間が都度判断して更新する
前回のキャプチャと比較
分岐元のキャプチャと比較
gitのコミットごとに画像を貯めておく
git branchが分岐した元の画像と比較する
Pros.
正答データと確実に比較できる
Cons.
正答データが変わると更新が必要
Pros.
自動で正答データが最新になる
Cons.
一度差分を見逃すと、次回以降検知できない
検知した差分を修正したときも差分が出る
Pros.
PR単位でmasterからの差分を確認できる
自動で正答データが更新される
Cons.
運用環境でのテストでは使えない
Gitの分岐元判定が難しい
1. 現在の外観をキャプチャ
2. 正答画像の取得
3. 画像の比較・レポート
ここは大差ない
画像diffツールに何が使われるかくらい
レポートは大抵HTMLで出てくる
誤差許容パラメタのほうが重要
差分をどの程度許容するか(px/%)
色の違いをどの程度まで一致とみなすか
それぞれ向き・不向きがある
運用環境でリリース毎や定期的に見るのか
PR単位でmasterからの差分を見るのか
ツールによって担当範囲や手法が違う
reg-suit
正答データ管理や通知をカスタマイズできる
現在の外観画像は別途用意が必要
BackstopJS
外観画像取得から比較まで全部やってくれる
実環境へのWebアクセス+正答データ明示のみ
Storybook
コンポーネント単位でレンダリング
ビジュアルテスト手法の分類
Misocaでの活用事例の紹介
運用での工夫や注意点
今後の展望・活用アイディア
まとめ
本番環境・ステージ環境のキャプチャ
実環境で前回との差分チェック
ローカル環境のキャプチャ
実環境で正答データとの差分チェック
帳票PDFのキャプチャ
PDFを描画し、正答データとの差分チェック
日次で、前日との差分を検知
キャプチャ: capybara-screenshot
正答管理: reg-suit simple-keygen(Jenkinsビルド番号をキー)
差分レポート: reg-suit
Slackの専用チャンネルに通知
差分があったら、問題ないかを見てスレッドに書く
リリース毎に、前回との差分を検知
本番環境と同じ仕組み
キャプチャ: capybara-screenshot
正答管理: reg-suit simple-keygen(Jenkinsビルド番号をキー)
差分レポート: reg-suit
リリース作業チャンネルに通知
差分があったら、問題ないかを見てスレッドに書く
必要なときに手動で実行
キャプチャ: BackstopJS
正答管理: BackstopJS(init, approve)
差分レポート: BackstopJS
ローカルで表示しづらい画面がある
外部連携など
環境によって描画に微妙な差が出る
正答データが集約できない
Dockerを使えば解決しそう
CSSを書く人がJavaScriptに慣れていた
通常CIで、正答データとの差分を検知
キャプチャ: MiniMagickでpdf -> pngに変換
正答管理: Gitコミット(approveモード実行で上書き)
差分レポート: MiniMagick
失敗した場合はPR Statusに反映
他のテストが失敗したときと同じ
Misocaのサービス上重要な部分
個別に整備する価値がある
現在手を入れている箇所なので、安心して触りたい
PDF生成処理が独立している
データを変えて網羅的にテストしやすい
ビジュアルテスト手法の分類
Misocaでの活用事例の紹介
運用での工夫や注意点
今後の展望・活用アイディア
まとめ
CSSでアニメーションやキャレットを切る
非同期読み込みは少し長めに待つ
画像も長めに待たないと出ない事がある
画面や状態がわかる画像名にする
「請求書編集画面-プルダウン-発行.png」など
ルールを作ってヘルパーメソッドを作ると良い
def disable_animations
page.execute_script(ANIMATIONS_DESABLE_SCRIPT)
end
ANIMATIONS_DISABLE_STYLE = <<~CSS
<!--
*, *:before, *:after {
/*CSS transitions*/
transition-property: none !important;
/*CSS transforms*/
transform: none !important;
/*CSS animations*/
animation: none !important;
}
-->
CSS
ANIMATIONS_DESABLE_SCRIPT = <<~"SCRIPT"
const style = document.createElement('style');
style.innerHTML = `#{ANIMATIONS_DISABLE_STYLE}`;
document.head.appendChild(style);
SCRIPT
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'
# ...
基本はただのCapybaraコード
ヘルパーメソッドをいくつか作っている
tour(view_name, path)
pathにvisitする
screenshot(state_name, full: bool, sleep: float)
現在の画面を(view_name + state_name)で保存する
fullなら縦幅を要素に合わせる
画面キャプチャ前にsleep秒待つ
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}" : pagename).save
# ブラウザウィンドをリサイズしていた場合、元に戻す
resize_to_default if full
end
コーナーケースを追求しすぎない
1ケースごとに実行がかなり遅くなる
実環境に対しては分散実行も負荷・競合リスクになる
重要 / 典型的なケースをテストする
1画面で複数の状態をテストする
一覧画面では複数項目でパターン網羅できる
どの程度、画像の誤差を許容するか
小さすぎると誤検知が増える(False Positive)
大きすぎると差異を見逃す(False Negative)
False Positiveが多すぎるとつらい
ブラウザレンダリングで数pxのdiffが出たりする
// regconfig.json
{
"core": {
"workingDir": ".reg",
"actualDir": "screenshots",
"thresholdPixel": 50,
"addIgnore": true,
"thresholdRate": 0,
"ximgdiff": {
"invocationType": "client"
}
},
// ...
}
本番/ステージでは意図通りのdiffが出る
お知らせの更新など、本番のデータ変更
実際のデザイン変更
Slackに通知してチェックする
スレッドがついてなければまだ誰も見ていない
差分検知時に確認する体制 / フローが重要
ビジュアルテスト手法の分類
Misocaでの活用事例の紹介
運用での工夫や注意点
今後の展望・活用アイディア
まとめ
表示に使うデータを揃える必要がある
created_atなども表示するなら揃える必要がある
既存のfeature specとは別にしたほうが扱いやすそう
rrrspecで分散実行している
画像を集約する必要がある
S3に吐いておけば良さそう
全部Vue.js化すればできる……
そう簡単にはできない
partial単位で画像を作れないか
必要なCSSだけ読み込めるように分ける
コンポーネントカタログ的なページをRailsでレンダリング
ページ全体をrenderしてから必要な要素以外をdisplay: hiddenにする
ビジュアルテスト手法の分類
Misocaでの活用事例の紹介
運用での工夫や注意点
今後の展望・活用アイディア
まとめ
よかった
リファクタで意図しないマージンにリリース前時点で気づけた
「意図通りにデザインが変わる」ことを確認できるのも安心できる
仕組みを作れば、保守コストは割と安い
DOM構造が変わってもほとんど直さずに動く
CIにかかる時間は増えるので、うまく妥協する
ビジュアルテストにもいろいろある
運用環境での差分検査が導入しやすい
重要な部分に絞って網羅的に検査するのもあり
普通のテストと違う運用が必要
False PositiveとFalse Negativeのバランスを取る
検知した差分が意図どおりか確認する体制・フロー