LoginSignup
85
85

More than 3 years have passed since last update.

Rails on DockerでRSpecのSystem testをSelenium Dockerを使ってやってみた。

Last updated at Posted at 2019-01-04

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が最初からインストールされたものです。

docker-compose.yml
  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_onchromeを指定することで、このあと$ docker-compose run web rspecでテスト実行する時にchromeコンテナが自動で起動するようにしてます。

RSpecを準備する

次にRails on DockerのアプリケーションにRSpecをインストールします。RSpecのSystem testはversion 3.7以上で動作します。

Gemfileにrspec-railsを追記します。

Gemfile
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のコンテナのブラウザを使用するように設定します。

/spec/rails_helper.rb
# ~~~
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を書き換えます。

.rspec
- --require spec_helper
+ --require rails_helper

これで設定は完了です!

System Testを書く

確認のためにテストを実行しておきましょう。まずはspecファイルを作っておきます。

$ mkdir spec/system
$ touch spec/system/sample_spec.rb

typesystemjstrueを設定することでheadless Chromeでテストすることができます。(js: trueがない場合はrack_testが実行される)

spec/system/sample_spec.rb
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サーバーにアクセスできるようになっています。

docker-compose.yml
  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を採用しているのでブラウザが起動しないです。
なのでオプションを消しておきましょう。

spec/rails_helper.rb
  # ~~~
  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を使ってやってみた、でした。

Reference

85
85
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
85
85