株式会社TECH LUCKという会社で代表兼エンジニアをしている齊藤です。
DXプロジェクト、開発プロジェクト、Rails開発などでお困りごとがありましたら弊社HPからご相談をいただけますと幸いです。
以下のような問題に対応することが可能です。
- プロジェクトでRailsエンジニアが足りなくて困っている
- Railsのバージョンアップをしたいがノウハウ・リソースが足りなくて困っている
- オフショア開発をしているが、要件の齟齬やコード品質が悪いので改善したい
また、Railsエンジニアも募集しておりますので、興味がありましたら弊社HPからご連絡いただけますと幸いです。
前提
RSpecでsystemテストをする際にDockerでSeleniumを導入して、テストを実行する方法になります。
Docker関連の設定
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
の以下を記述します。
コメントアウトになっていますが、こちらを復活させる形で大丈夫です。
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }
spec/support/
のディレクトリに、capybara.rb
を作成し以下の記述をします。
これによってdocker-compose
で構築されたコンテナ同士で通信してChromeが使えるようになります。
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をインストールして利用する形にします。
以下の記述を追加します。
- name: Chrome Install
run: sudo apt-get install google-chrome-stable
その後、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を使う形になります。
参考文献