LoginSignup
5
2

M1 MacでRails + Docker + RSpec + CapybaraでのSystemテストの環境構築

Posted at

株式会社TECH LUCKという会社で代表兼エンジニアをしている齊藤です。

RSpecでsystemテストをする際にDockerでSeleniumを導入して、テストを実行する方法になります。

Docker関連の設定

docker-compose.yml
version: '3.7'
services:
  db:
    image: mysql:8.0
    platform: linux/x86_64
    command: --default-authentication-plugin=mysql_native_password
    ports:
      - "4306:3306"
    volumes:
      - db:/var/lib/mysql
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
    security_opt:
      - seccomp:unconfined
  webpacker:
    build: .
    volumes:
      - .:/myapp
      - bundle:/usr/local/bundle
    command: ./bin/webpack-dev-server
    environment:
      WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
    ports:
      - "3035:3035"
  web:
    build: .
    stdin_open: true
    tty: true
    volumes:
      - .:/myapp
      - bundle:/usr/local/bundle
    command: bash -c "rm -rf tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    depends_on:
      - db
    ports:
      - "3000:3000"
    environment:
      WEBPACKER_DEV_SERVER_HOST: webpacker
      SELENIUM_DRIVER_URL: http://selenium_chrome:4444/wd/hub
  selenium_chrome:
    image: seleniarm/standalone-chromium
    ports:
      - "4444:4444"
volumes:
  db:
    driver: local
  bundle:
    driver: local

注意する点はselenium_chromeのイメージはselenium/standalone-chrome:latestを使っている記事が多いです。しかし、M1の場合だとこのイメージだとエラーが出てしまい動きません(これに気づくのに丸2日潰してしまった、、、。)。そのため、seleniarm/standalone-chromiumのイメージを使います。

rails_helper.rbの以下を記述します。
コメントアウトになっていますが、こちらを復活させる形で大丈夫です。

spec/rails_helper.rb
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }

spec/support/のディレクトリに、capybara.rbを作成し以下の記述をします。
これによってdocker-composeで構築されたコンテナ同士で通信してChromeが使えるようになります。

spec/support/capybara.rb
require 'capybara/rspec'
require 'selenium-webdriver'

Capybara.register_driver :remote_chrome do |app|
  url = ENV["SELENIUM_DRIVER_URL"]
  capabilities = ::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,
                                 capabilities: capabilities)
end

RSpec.configure do |config|
  config.before(:each, type: :system) do
    driven_by :rack_test
  end

  config.before(:each, type: :system, js: true) do
    Capybara.server_host = IPSocket.getaddress(Socket.gethostname)
    Capybara.server_port = 4444
    Capybara.app_host = "http://#{Capybara.server_host}:#{Capybara.server_port}"
    driven_by :remote_chrome
  end
end

GitHub Actionsへの対応

CI/CDでテストを実現するために、GitHub Actionsを利用する場合の設定を書きます。
GitHub Actionsで立ち上がるコンテナにChromeをインストールして利用する形にします。

以下の記述を追加します。

.github-action.yml
- name: Chrome Install
  run: sudo apt-get install google-chrome-stable

その後、capybara.rbを変更します。

capybara.rb
require 'capybara/rspec'

Capybara.register_driver :remote_chrome do |app|
  url = ENV['SELENIUM_DRIVER_URL']
  capabilities = ::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,
                                 capabilities: capabilities)
end

RSpec.configure do |config|
  config.before(:each, type: :system) do
    driven_by :rack_test
  end

  config.before(:each, type: :system, js: true) do
    if ENV['SELENIUM_DRIVER_URL']
      Capybara.server_host = IPSocket.getaddress(Socket.gethostname)
      Capybara.server_port = 4444
      Capybara.app_host = "http://#{Capybara.server_host}:#{Capybara.server_port}"
      driven_by :remote_chrome
    else
      driven_by :selenium_chrome_headless
    end
  end
end

これで環境変数にSELENIUM_DRIVER_URLがある場合、つまり、docker-composeで起動したrailsコンテナの中では、Dockerコンテナで立ち上がっているSelenium(remote_chrome)を使う形になります。
環境変数にSELENIUM_DRIVER_URLがない場合、つまりローカルでの開発の場合は、Github Actions内ではその環境内にインストールされているChromeを使う形になります。

参考文献

5
2
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
5
2