LoginSignup
9
3

More than 3 years have passed since last update.

Docker環境にSystem Specを導入する

Posted at

はじめに

Docer環境でRSpecのSystem Specを導入しようとしたところ、結構ハマったので、備忘録としてまとめます。

まず、Docer環境にSystem Specを実行するためには、いくつか方法があるらしい。
調査をしていると、メジャーな方法は以下の二つ(もっとあるかもしれませんが、、、)

1. Railsが動いているimageにchromeをインストールする方法
2. chrome用コンテナを立ち上げる方法

今回は2の方法でやってみました。

前提

Quickstart: Compose and Railsの通りに、Rails on Dockerの環境構築が済んでいる状態とします。
筆者の環境は
- Ruby 2.5.7
- Rails 5.2.4
です。

docker-compose.ymlを編集する

selenium_chromeのコンテナが立ち上がるようdocker-compose.ymlに追加していきます。
Dockerイメージにはselenium/standalone-chromeを使用します。

docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && 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:3.141.59-dubnium
    ports:
      - 4444:4444

gemを追加する

Gemfile

group :development, :test do
  gem 'rspec-rails'
end

group :test do
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
end

dockerをbuildして、bundle installします。

$ docker-compose build
$ docker-compose up -d

rspecの設定

rspecをインストールします。

$ docker-compose run web rails g rspec:install

headless chromeの設定

spec/rails_helper.rbにheadless chromeの設定を追加していきます。

/spec/rails_helper.rb
require 'capybara/rspec'

# headless chrome 設定①
Capybara.server_host = Socket.ip_address_list.detect { |addr| addr.ipv4_private? }.ip_address
Capybara.server_port = 3001   

Capybara.register_driver :selenium_remote do |app|
  url = "http://chrome:4444/wd/hub"
  opts = { desired_capabilities: :chrome, browser: :remote, url: url }
  Capybara::Selenium::Driver.new(app, opts)
end


 # headless chrome 設定②
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 :selenium_remote
    host! "http://#{Capybara.server_host}:#{Capybara.server_port}"
  end
end

ポイント:
後半部分(# headless chrome 設定②)で、
js: trueを記述した場合のみ、seleniumドライバーが立ち上がるように設定しています。

ハマったポイント:
js: trueのテストを走らせたとき、Capybaraがseleniumサーバーを立ち上げて、先ほど設定したchromeコンテナで起動しているchromeを操作します。
しかし、Capybara.server_portを指定する部分(*)で、webコンテナで指定したポートと同じ3000を指定してしまうと、js: trueのテストを走らせたときに、webコンテナで指定したポートと競合してseleniumサーバーが立ち上がらずエラーとなってしまいます。
そこで、Capybara.server_port = 3000 3001
とすることで、競合することなく、無事サーバーが立ち上がり、テストが通るようになりました。

これで準備は整いました。
あとは、テストを実際に走らせるだけです。

実際にテストを走らせてみる

spec/system/test_spec.rb
require "rails_helper"

RSpec.describe 'Test', type: :system, js: true do
  example 'サンプルテスト' do
    #ここにテスト内容を記述
  end
end
$ docker-compose exec web bundle exec rpsec

これで、テストが通るはずです。

参考記事

下記の記事を参考にさせていただきました。
ありがとうございます。
- Docker で RSpec の System Spec を実行するための設定メモ
- Rails + Selenium + DockerでSystemSpecの環境構築
- Rails on Dockerにて、Headless ChromeでSystem Testをやってみた。

9
3
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
9
3