Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
67
Help us understand the problem. What is going on with this article?
@at-946

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

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

67
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
at-946
ゆっくりと。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
67
Help us understand the problem. What is going on with this article?