ヘッドレス Chromeで始めるE2Eテスト

皆さんテスト書いてますか?今日はヘッドレス Chromeを使ってRails上でE2Eテストを試してみたいと思います。

週末に今年の夏初めてのプールに行って日焼けで肌がヒリヒリしているエンジニアの三宅です。

ヘッドレス ChromeについてはGoogleのエンジニアによって書かれた記事を一読しておきましょう。

ヘッドレス Chrome ことはじめ  |  Web  |  Google Developers
https://developers.google.com/web/updates/2017/04/headless-chrome

ヘッドレス Chromeを試してみる

記事に書かれた内容を参考に、まずはヘッドレス Chromeをコマンドラインから使ってみましょう。

$ chrome --headless --disable-gpu --remote-debugging-port=9222 https://timecrowd.net
[0903/094149.841575:WARNING:dns_config_service_posix.cc(181)] dns_config has unhandled options!
[0903/094149.843062:ERROR:gpu_process_transport_factory.cc(1016)] Lost UI shared context.

DevTools listening on ws://127.0.0.1:9222/devtools/browser/0f990964-6a8f-4258-9908-01d2d507032b
[0903/094149.939474:ERROR:gl_implementation.cc(292)] Failed to load /Applications/Google Chrome.app/Contents/Versions/68.0.3440.106/Google Chrome Framework.framework/Versions/Current/Libraries/libswiftshader_libGLESv2.dylib: dlopen(/Applications/Google Chrome.app/Contents/Versions/68.0.3440.106/Google Chrome Framework.framework/Versions/Current/Libraries/libswiftshader_libGLESv2.dylib, 1): image not found
[0903/094150.146802:ERROR:gl_implementation.cc(292)] Failed to load /Applications/Google Chrome.app/Contents/Versions/68.0.3440.106/Google Chrome Framework.framework/Versions/Current/Libraries/libswiftshader_libGLESv2.dylib: dlopen(/Applications/Google Chrome.app/Contents/Versions/68.0.3440.106/Google Chrome Framework.framework/Versions/Current/Libraries/libswiftshader_libGLESv2.dylib, 1): no suitable image found.  Did find:
        /Applications/Google Chrome.app/Contents/Versions/68.0.3440.106/Google Chrome Framework.framework/Versions/Current/Libraries/libswiftshader_libGLESv2.dylib: file system sandbox blocked stat()
[0903/094150.179793:ERROR:viz_main_impl.cc(201)] Exiting GPU process due to errors during initialization

なにやら色々エラーが出ていますがひとまず無視しておきます。

--remote-debugging-portでポートを指定すると、http://localhostに指定したポートでアクセスするとヘッドレス Chromeがレンダリングしている内容を確認することができます。

 

フラグを利用することでコマンドラインで色々なことができるようです。試しにスクリーンショットを撮ってみましょう。

$ chrome --headless --disable-gpu --screenshot https://timecrowd.net

するとコマンドを実行した同じパス上にscreenshot.pngというファイルが出来上がっていました。

Rails + Capybara + ヘッドレス Chrome

ではここからはRailsアプリでヘッドレス Chromeを使ったE2Eテストを試してみることにします。

まずは必要なgemをインストールします。

group :test do
  gem 'capybara'
  gem 'chromedriver-helper'
  gem 'selenium-webdriver'
end

ChromeをSeleniumで実行させるためにはChromeDriverが必要です。

chromedrive-helperは各OSに合わせたバイナリを取ってくることができるようになるようです。

またヘッドレス Chromeとchromedriverのバージョン関係が意外に厳しいので、うまくいかないときはchromedriver-helperの設定で簡単に使用するバージョンを変更することができます。

Chromedriver.set_version "2.24"

あとはcapybaraのREADMEを参考に基本的な設定をセットアップしてdriverにselenium_chrome_headlessを指定して上げるだけで、ヘッドレス Chromeを使ってテストを実行してくれるようになります。

require 'capybara/rails'
require 'capybara/rspec'
Capybara.javascript_driver = :selenium_chrome_headless

もしヘッドレス Chromeの起動オプションを変更して実行したい場合には以下のようにdriverを再登録してあげるだけでOKです。

Capybara.register_driver :selenium_chrome_headless do |app|
  Capybara::Selenium::Driver.new(
    app,
    browser: :chrome,
    desired_capabilities: Selenium::WebDriver::Remote::Capabilities.chrome(
      chrome_options: {
        args: %w[headless disable-gpu window-size=1680,1050],
      },
    )
  )
end

まとめ

今回はヘッドレス Chromeを使ってE2Eテストを書くまでのセットアップの方法を紹介しました。

手動テストは時間がかかったり、ムラがでてきてしまったりするので、ガシガシ自動化していきたいですね。ただE2Eテストは遅いという欠点もあるので、すべての機能をまんべんなくやるのではなく、主要な機能を抽出して実行するなど、バランスよく取り入れていきましょう。

TimeCrowdに戻る