[Day 2: C-12] Misocaにおけるビジュアルテストへの取り組み


yhirano55
yhirano55 commented 6 months

登壇者: 株式会社Misoca 森 俊介

RailsアプリケーションのE2Eテストでは一般的にDOMツリーのみを検証するため、デザインの崩れは検知できません。

こうした「見た目」の変化を検知するためのテストがビジュアルテストです。

本セッションでは、capybara screenshotとreg-suitを利用したビジュアルテストの取り組みをご紹介します。


  • このセッションに関する質問を募集中です
  • 事前に聞きたいことがあれば、何でも書き込んでください。
  • 質問への回答はお約束できません。あらかじめご了承ください

Like(0)

Questions and feedbacks (4)

kokuyouwind
kokuyouwind commented 6 months

画像差分を愚直に使うだけだともう一工夫必要に感じたのですが、この辺りの知見があるととても興味があります。 その他にもこんなテクニックあるよ、みたいなものあれば

他のテクニックですと、外部スクリプトで差し込まれるチャットサポートのタグが出たり出なかったりする問題があったため、それをスクリーンショットの直前に消すようにしていますね。 page.execute_script 'typeof $ !== "undefined" && $(".LPMcontainer") && $(".LPMcontainer").css("display", "none")' のような感じです。 こういうときにはjQueryが入ってると便利ですね。

ただ消すだけだとレイアウトが崩れてしまうので、仰る通りダミーコンテンツに差し替えたりhiddenにするなどしてもよいかもしれません。

いじる要素が増えてくると複雑になってしまいますが、こういった感じでスタイルを直接いじってやるのは応用が効くかなと思います。 例えば、時間経過で変わってしまう「X日前」のような表示を固定の内容に差し替えてしまう、などしてやればうまくテストできるようになりそうです。

Like(1)

kokuyouwind
kokuyouwind commented 6 months

puppeteer でスクショがたまに部分的にしか撮られない事象に悩まされているのですが、 misoca さんではドライバは何を使っていますか? たぶん selenium 経由で chrome ですかね?

そのとおりで、Selenium + headless Chromeですね。 特に秘匿情報はないので、spec_helperのセットアップコードを載せておきます。

Capybara.register_driver :headless_chrome do |app|
  options = Selenium::WebDriver::Chrome::Options.new
  options.add_argument('headless')
  options.add_argument('disable-gpu')
  options.add_argument('lang=ja-JP')
  options.add_argument("window-size=#{ENV['WINDOWS_DEFAULT_WIDTH']},#{ENV['WINDOWS_DEFAULT_HEIGHT']}")

  driver = Capybara::Selenium::Driver.new(
    app,
    browser: :chrome,
    options: options
  )
  bridge = driver.browser.send(:bridge)
  bridge.http.call(
    :post,
    "session/#{bridge.session_id}/chromium/send_command",
    cmd: 'Page.setDownloadBehavior',
    params: {
      behavior: 'allow',
      downloadPath: Dir.pwd + '/screenshots'
    }
  )
  driver
end

Capybara::Screenshot.register_driver(:headless_chrome) do |driver, path|
  driver.browser.save_screenshot(path)
end

Capybara.configure do |config|
  config.run_server = false
  config.default_driver = :headless_chrome
  config.app_host = ENV['APP_HOST']
  config.default_max_wait_time = 10
  config.save_path = 'screenshots'
end

# 前回実行分だけ残して、後は削除する。
Capybara::Screenshot.prune_strategy = :keep_last_run
# 撮影サイズが標準だと狭いので広げる。
Capybara::Screenshot.webkit_options = { width: 1600, height: 1200 }
# スクリーンショット名にタイムスタンプを付けない
Capybara::Screenshot.append_timestamp = false

同様の症状は起きていますか?

うーん、起きていないですね… 読み込みの問題なら少し眺めにsleepすれば解決するかもしれませんが、多分そういう感じの欠け方でもないんですよね。

Like(1)

mtsmfm
mtsmfm commented 6 months

puppeteer でスクショがたまに部分的にしか撮られない事象に悩まされているのですが、 misoca さんではドライバは何を使っていますか? たぶん selenium 経由で chrome ですかね? また、同様の症状は起きていますか?

Like(0)

morimorihoge

Visual Regression Test、試してみたことはあるのですが、埋め込まれている外部スクリプトの広告機能などがdiffとして反応してしまったりして今一つ使ってみたプロジェクトでは誤検知が多かった印象でした。発表でもランダム要素があるとうまくいかないと挙げられていた部分ですね。
ほかにもアニメーションなどが含まれているとスクショが撮られるタイミングによって差分が出てしまったりなど、画像差分を愚直に使うだけだともう一工夫必要に感じたのですが、この辺りの知見があるととても興味があります。

※E2Eテストの時だけ当該DOMを固定ダミーコンテンツに差し替えるなど?こうするといいよ、的なものがあればぜひ

(追記) -> 具体例出していただけましたね、ありがとうございます!その他にもこんなテクニックあるよ、みたいなものあれば

Like(1)

Create Comment

Please sign in to comment.

Sign in with GitHub
This software is available as open source under the terms of the MIT License.
Copyright © 2018 Yoshiyuki Hirano