Rails on DockerでRSpecのSystem testをChromeでやるときのメモです。
Rails on Dockerはこちらなどを参考にしてます。
Headless Chromeは今回はdocker-seleniumのDockerコンテナを使うようにします。
docker-compose.yml
を編集する
まずはdocker-seleniumを使えるようにdocker-compose.yml
を編集する。
docker-seleniumの中でもstandalone-chromeを使います。このイメージはChromeが最初からインストールされたものです。
version: '3'
services:
db:
image: postgres
volumes:
- ./myapp/db:/var/lib/postgresql/data
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/myapp
ports:
- "3000:3000"
depends_on:
- db
+ - chrome
+ chrome:
+ image: selenium/standalone-chrome:latest
+ ports:
+ - 4444:4444
services.web.depends_on
にchrome
を指定することで、このあと$ docker-compose run web rspec
でテスト実行する時にchrome
コンテナが自動で起動するようにしてます。
RSpecを準備する
次にRails on DockerのアプリケーションにRSpecをインストールします。RSpecのSystem testはversion 3.7以上で動作します。
Gemfileにrspec-railsを追記します。
group :development, :test do
gem 'capybara', '>=2.15'
gem 'selenium-webdriver'
gem 'rspec-rails', '~>3.9'
end
bundle install
するためにDockerイメージをビルドします。
$ docker-compose build
次に、Dockerコンテナを起動させてRSpecをインストールしていきます。
$ docker-compose run web rails g rspec:install
RSpecがインストールできたらrails_helper.rb
を編集してRSpec実行時にdocker-selenium
のコンテナのブラウザを使用するように設定します。
# ~~~
Capybara.register_driver :remote_chrome do |app|
url = "http://chrome:4444/wd/hub"
caps = ::Selenium::WebDriver::Remote::Capabilities.chrome(
"goog:chromeOptions" => {
"args" => [
"no-sandbox",
"headless",
"disable-gpu",
"window-size=1680,1050"
]
}
)
Capybara::Selenium::Driver.new(app, browser: :remote, url: url, desired_capabilities: caps)
end
RSpec.configure do |config|
config.before(:each, type: :system) do
driven_by :rack_test
end
config.before(:each, type: :system, js: true) do
driven_by :remote_chrome
Capybara.server_host = IPSocket.getaddress(Socket.gethostname)
Capybara.server_port = 3000
Capybara.app_host = "http://#{Capybara.server_host}:#{Capybara.server_port}"
end
# ~~~
end
remote_chrome
というドライバーを定義してjs: true
の場合利用するようにしています。
画面表示の必要はないので、高速化のためにheadless
を採用します(ブラウザの起動がない分高速!)
デフォルトでrails_helper.rb
を設定ファイルとして読み取るように.rspec
を書き換えます。
- --require spec_helper
+ --require rails_helper
これで設定は完了です!
System Testを書く
確認のためにテストを実行しておきましょう。まずはspecファイルを作っておきます。
$ mkdir spec/system
$ touch spec/system/sample_spec.rb
type
にsystem
、js
にtrue
を設定することでheadless Chromeでテストすることができます。(js: true
がない場合はrack_test
が実行される)
feature 'sample', type: :system, js: true do
scenario 'sample scenario' do
# 例えばルートパスにアクセスできることを確認
visit root_path
expect(current_path).to eq root_path
end
end
テストを実行する
$ docker-compose run web rspec spec/system/sample_spec.rb
動いてるの見る
テストをしていると、ちゃんと動作しているのかブラウザ操作をみたいこともあるときとおもいます。その場合はselenium-chromeの代わりにselenium-chrome-debugを使います。
docker-compose.yml
を以下のように、Dockerイメージの変更とポートの追加をします。selenium-chrome-debugでは5900ポートからVNCサーバーにアクセスできるようになっています。
version: '3'
services:
db:
image: postgres
volumes:
- ./myapp/db:/var/lib/postgresql/data
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/myapp
ports:
- "3000:3000"
depends_on:
- db
- chrome
chrome:
- image: selenium/standalone-chrome:latest
+ image: selenium/standalone-chrome-debug:latest
ports:
- 4444:4444
+ - 5900:5900
また、上の設定ではheadless
を採用しているのでブラウザが起動しないです。
なのでオプションを消しておきましょう。
# ~~~
Capybara.register_driver :remote_chrome do |app|
url = "http://chrome:4444/wd/hub"
caps = ::Selenium::WebDriver::Remote::Capabilities.chrome(
"goog:chromeOptions" => {
"args" => [
"no-sandbox",
- "headless",
"disable-gpu",
"window-size=1680,1050"
]
}
)
Capybara::Selenium::Driver.new(app, browser: :remote, url: url, desired_capabilities: caps)
end
# ~~~
ではテストを実行していきましょう!
まず、chrome
コンテナを立ち上げておき、VNCで接続しておきます。
$ docker-compose up -d chrome
$ open vnc://localhost:5900
パスワードを求められるので「secret」と入力してください。これでブラウザが立ち上がるサーバーが表示されている状態になりますのでRSpecでテストを実行してみてください。
$ docker-compose run web rspec
テストに合わせてブラウザが立ち上がり、操作が行われていくのが見れるはずです。
以上、Rails on DockerでRSpecのSystem testをSelenium Dockerを使ってやってみた、でした。