はじめに
Ruby on Railsの入門書籍として知られる”速習実践ガイド”
とても勉強になる良い書籍ですが、いかんせんRubyやRailsのバージョンが古いこと、手元の環境がMac M1が相まって開発環境構築に難儀しました。
そこで、試行錯誤の末、RSpecが動くまでの環境を残したいと思います。
これからRuby on Railsを始める方、速習実践ガイドを始める方のお役に立てれば幸いです。
環境構築
手元環境
- Macbook Air M1
- Docker Desktop
dockerfile
dockerfileは以下の通りです。
こちらのサイトを参考に構築しています。
速習実践ガイドのRuby2.5なので、それに合わせています。
# syntax=docker/dockerfile:1
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
# コンテナー起動時に毎回実行されるスクリプトを追加
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# イメージ実行時に起動させる主プロセスを設定
CMD ["rails", "server", "-b", "0.0.0.0"]
entrypoint.sh
#!/bin/bash
set -e
# Rails に対応したファイル server.pid が存在しているかもしれないので削除する。
rm -f /myapp/tmp/pids/server.pid
# コンテナーのプロセスを実行する。(Dockerfile 内の CMD に設定されているもの。)
exec "$@"
docker-compose.yaml
docker-compose.yamlは以下の通りです。
RSpecでシステムテストを実行するためには、ブラウザが必要です。
ただ、webコンテナの中にブラウザをインストールするのは大変です。
なので、docker-compose.yamlで別途ブラウザ用のコンテナを用意します。
webコンテナのdepends_onとenvironmentでブラウザ用コンテナを利用するように設定します。
version: "3.9"
services:
db:
image: postgres
volumes:
- ./tmp/db:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: password
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
environment:
SELENIUM_DRIVER_URL: http://webdriver_chrome:4444/wd/hub
volumes:
- .:/myapp
ports:
- "3000:3000"
depends_on:
- db
- webdriver_chrome
webdriver_chrome:
image: seleniarm/standalone-chromium
ports:
- "4444:4444"
Gemfile
続いて、Gemfileです。
bin/rails new で追加されるモジュールの一部は省略しています。
速習実践ガイドでは Headless Chromeが紹介されています。しかし、このChromeは今はあまり使われていないようです(よくわかってないです)
なので、group :test do
の箇所にはgem 'selenium-webdriver'
を指定します。
また、Rubyのバージョンですが、速習実践ガイドのバージョンは素直に使えなかったので、2.5.9に変更しています。
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '2.5.9'
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
gem 'rspec-rails', '~> 3.7'
gem 'factory_bot_rails', '~> 4.11'
end
group :development do
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
gem 'web-console', '>= 3.3.0'
gem 'listen', '>= 3.0.5', '< 3.2'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
group :test do
# Adds support for Capybara system testing and selenium driver
gem 'capybara', '>= 2.15'
gem 'selenium-webdriver'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
gem 'slim-rails'
gem 'html2slim'
gem 'bootstrap'
gem 'rails_autolink'
RSpecの設定
続いて、RSpecの設定です。
まずspec/rails_helper.rbの25行目あたりの記述をコメントインします。
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }
続いて、spec/support/capybara.rb をフォルダ含めて作成します。
capybara.rbの内容は以下の通りです。
require 'capybara/rspec'
RSpec.configure do |config|
config.before(:each, type: :system) 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
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
# Chrome
Capybara.register_driver :remote_chrome do |app|
url = 'http://webdriver_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
実行方法
ここまでで、設定は終了です。
最後に環境の実行方法は以下の通りです
$ docker compose build
$ docker compose up
補足情報
残りは実行時に詰まりそうな情報です。
RSpec Systemテストが失敗する
私の環境では、チュートリアル通りに進めたところ、fill_inが正しく動作せず、入力失敗していました。
こちらの方の情報通りに直して動作しました。click_onは念の為、生成されるボタンのcommitを指定しました。
【RSpec/capybara】fill_inが上手く動作しな
before do
visit login_path
fill_in 'session_email', with: 'a@example.com'
fill_in 'session_password', with: 'password'
click_on 'commit'
end
Docker環境でのコマンド実行の方法
Dockerで構築したwebコンテナで速習実践ガイドで紹介されているコマンドを実行する場合は以下の通りです。
$ docker compose run web {実行したいコマンド}
# 例えば、db:migrationやrailsコマンドを実行したい場合
$ docker compose run web db:migrate
$ docker compose run web bin/rails g controller
gemを追加する方法
gemfileに新しいモジュールを追加した場合、コマンド実行だけでは不十分です。
必ずBuildしましょう。何が動作がおかしい場合は、--no-cacheコマンドでしっかりBuildしましょう。
$ docker compose build
以上です。皆様の参考になれば幸いです。