はじめに
この記事は、タイトルのとおり、「Everyday Rails」を Rails 6 で勉強したいので、
書籍の翻訳者である伊藤さんのブログを参考にして頑張ってみた記録を記したものである。
記事自体が長くなったので、導入編・前編・中編・後編に分割している。
Rails 6 へのアップグレードは非常に時間がかかるので、いきなり挑戦するのではなく、
まず導入編を読んでいただき、本当に挑戦するのか検討することを強く勧めます。
導入編・中編・後編については、以下を参照すること。
【導入編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita
【中編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita
【後編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita
また、本記事は、伊藤さんのyoutube動画を見ながら作業した内容の実況中継に
近いような形で書き進めているので、以下を必ず併せて視聴してください。
(youtube動画を視聴している前提で書いているので、この記事単体だと意味が通じない)
【前編】永久保存版!?伊藤さん式・Railsアプリのアップグレード手順(youtube動画)
【後編】永久保存版!?伊藤さん式・Railsアプリのアップグレード手順(youtube動画)
作業を始める前に
「Everyday Rails - RSpecによるRailsテスト入門」のサンプルアプリについては、
伊藤さんのyoutube動画を見ながら作業すると、以下のとおりアップグレードできる。
変更前の環境 | 変更後の環境 | |
---|---|---|
Rails | 5.1.1 | 6.0.0 |
rspec-rails | 3.8.0 | 4.0.0.beta2(正式版は3.9.0) |
Ruby | 2.4.9 | 2.6.5 |
その他のgem | - | できる限り最新化 |
(2019年10月時点の最新環境) |
なお、私は以下のとおりアップグレードした。
なぜと思うところがあるかもしれないが、
初学者なので何となく最新版にしてみたとしか言いようがない。
変更前の環境 | 変更後の環境 | |
---|---|---|
Rails | 5.1.1 | 6.0.3.2 |
rspec-rails | 3.8.0 | 4.0.1 |
Ruby | 2.4.9 | 2.7.1 |
その他のgem | - | できる限り最新化 |
(2020年6月18日時点の最新環境・・・と思われる) |
あと、初学者なので話半分で聞いてもらいたいが、rubyは2.7.1にしない方がよいような気がする。
様々なgem
との互換性の問題があるためか、警告が大量に出てくる。覚悟して使いましょう。
また、私はヒヨってRailsのバージョンは、6.0.0でよいと思って作業を進めていたが、
gem 'rails', '~> 6.0.0'
と書いていたので、結果として最新版に更新できていた。
ブログ内で気になる部分があるかもしれないが、
本人は、Rails 6.0.0 にアップグレードするつもりで頑張っている。
生温かい目で見守ってもらいたい。
伊藤さんのyoutube動画の構成
伊藤さんは、ご自身が書いたRailsアプリのアップグレード手順を参考にして、
順を追ってRSpecのサンプルアプリをアップグレードしている。
以下がそのアップグレード手順を記したQiita記事である。
この記事では、このアップグレード手順に準拠する形で章立てをする。
1. 公式のアップグレードガイドに目を通す
私はほぼ目を通しませんでしたが、通すと勉強になるかと思います。。。
2. テストが全部パスすることを確認する
動画では、テストが全てパスするか確認するよう指示が出ている。
RSpecでのテストは以下のコマンドで実行できる。
bin/rspec
Specテストでいきなりパスしない!
やってみると、下記の記事で紹介されているようなエラーが出た。
どうやら、Rubyのバージョンが問題であるようなので、大人しくRubyを2.4.9に指定することにした。
私は、Rbenvを使っているのだが、使い方を忘れているので、以下を参照して対応した。
# ruby 2.4.9 をダウンロードする
rbenv install 2.4.9
# rubyのバージョンを 2.4.9 に指定する
rbenv local 2.4.9
# rubyのバージョンが 2.4.9 になっていることを確認する
rbenv version
無事、Rubyのバージョンを2.4.9に合わせることができた。
また、Specテストにパスしない!
RSpecで再テストすると、以下のとおりエラーが出た。
Failures:
1) Tasks user toggles a task
Got 0 failures and 2 other errors:
1.1) Failure/Error: visit root_path
Selenium::WebDriver::Error::SessionNotCreatedError:
session not created: This version of ChromeDriver only supports Chrome version 81
1.2) Failure/Error: Unable to infer file and line number from backtrace
Selenium::WebDriver::Error::SessionNotCreatedError:
session not created: This version of ChromeDriver only supports Chrome version 81
Finished in 27.03 seconds (files took 1.18 seconds to load)
70 examples, 1 failure
Failed examples:
rspec ./spec/system/tasks_spec.rb:12 # Tasks user toggles a task
Pythonの話がベースだが、以下の記事を参考にした。
どうやら、私が使っているChromeのバージョンとの不一致が問題である可能性が高い。
Chromeのバージョンを確認すると、以下のとおりバージョンが83だった。
エラーメッセージを見直してみると、Everyday Railsの方ではバージョンが81を要求している。
ここでバージョンのダウングレードをしてもよいのだが、
そもそもRailsのバージョンを6にアップグレードした際に、
chromedriver-helper
をwebdrivers
に変更するよう指示が出ているので、
ここはスルーすることにする。
3. 開発用ブランチを作成する
ちょくちょくブランチを切りましょう。
保険は大事です。
4. Rails以外のgemをバージョンアップする
さて、指示のとおりブランチを作成した後、Rails以外のgem
をバージョンアップする。
なお、一度失敗しているので、ここの記述はかなり冗長である。
4-a. 最新ではないgemを探す(第1チャレンジ)
gem
が最新か確認するように指示があるのでbundle outdated
を実行してみる。
outdated gems included in the bundle:
* actioncable (newest 6.0.3.1, installed 5.1.1)
* actionmailer (newest 6.0.3.1, installed 5.1.1)
* actionpack (newest 6.0.3.1, installed 5.1.1)
* actionview (newest 6.0.3.1, installed 5.1.1)
* activejob (newest 6.0.3.1, installed 5.1.1)
* activemodel (newest 6.0.3.1, installed 5.1.1)
* activerecord (newest 6.0.3.1, installed 5.1.1)
* activesupport (newest 6.0.3.1, installed 5.1.1)
* addressable (newest 2.7.0, installed 2.5.2)
* archive-zip (newest 0.12.0, installed 0.11.0)
* arel (newest 9.0.0, installed 8.0.0)
* autoprefixer-rails (newest 9.7.6, installed 6.7.7.2)
* bcrypt (newest 3.1.13, installed 3.1.12)
* bindex (newest 0.8.1, installed 0.5.0)
* bootstrap-sass (newest 3.4.1, installed 3.3.7) in group "default"
* builder (newest 3.2.4, installed 3.2.3)
* byebug (newest 11.1.3, installed 9.0.6) in groups "development, test"
* capybara (newest 3.32.2, installed 2.15.4, requested ~> 2.15.4) in group "test"
* childprocess (newest 3.0.0, installed 0.8.0)
* chromedriver-helper (newest 2.1.1, installed 1.2.0) in group "test"
* cocaine (newest 0.6.0, installed 0.5.8)
* coffee-rails (newest 5.0.0, installed 4.2.1, requested ~> 4.2) in group "default"
* concurrent-ruby (newest 1.1.6, installed 1.0.5)
* crass (newest 1.0.6, installed 1.0.4)
* devise (newest 4.7.2, installed 4.4.3) in group "default"
* erubi (newest 1.9.0, installed 1.7.1)
* factory_bot (newest 5.2.0, installed 4.10.0)
* factory_bot_rails (newest 5.2.0, installed 4.10.0, requested ~> 4.10.0) in groups "development, test"
* faker (newest 2.12.0, installed 1.7.3) in group "development"
* ffi (newest 1.13.1, installed 1.9.18)
* geocoder (newest 1.6.3, installed 1.4.9) in group "default"
* globalid (newest 0.4.2, installed 0.4.0)
* hashdiff (newest 1.0.1, installed 0.3.4)
* i18n (newest 1.8.3, installed 0.9.5)
* io-like (newest 0.3.1, installed 0.3.0)
* jbuilder (newest 2.10.0, installed 2.6.3, requested ~> 2.5) in group "default"
* jquery-rails (newest 4.4.0, installed 4.3.1) in group "default"
* launchy (newest 2.5.0, installed 2.4.3, requested ~> 2.4.3) in group "test"
* listen (newest 3.2.1, installed 3.1.5, requested < 3.2, >= 3.0.5) in group "development"
* loofah (newest 2.6.0, installed 2.2.2)
* mail (newest 2.7.1, installed 2.6.5)
* method_source (newest 1.0.0, installed 0.9.0)
* mime-types (newest 3.3.1, installed 3.1)
* mime-types-data (newest 3.2020.0512, installed 3.2016.0521)
* mimemagic (newest 0.3.5, installed 0.3.2)
* mini_mime (newest 1.0.2, installed 0.1.4)
* mini_portile2 (newest 2.5.0, installed 2.3.0)
* minitest (newest 5.14.1, installed 5.11.3)
* multi_json (newest 1.14.1, installed 1.12.1)
* nio4r (newest 2.5.2, installed 2.0.0)
* nokogiri (newest 1.10.9, installed 1.8.4)
* paperclip (newest 6.1.0, installed 5.1.0) in group "default"
* public_suffix (newest 4.0.5, installed 3.0.0)
* puma (newest 4.3.5, installed 3.8.2, requested ~> 3.7) in group "default"
* rack (newest 2.2.3, installed 2.0.5)
* rack-test (newest 1.1.0, installed 0.6.3)
* rails (newest 6.0.3.1, installed 5.1.1, requested ~> 5.1.1) in group "default"
* rails-html-sanitizer (newest 1.3.0, installed 1.0.4)
* railties (newest 6.0.3.1, installed 5.1.1)
* rake (newest 13.0.1, installed 12.3.1)
* rb-fsevent (newest 0.10.4, installed 0.9.8)
* rb-inotify (newest 0.10.1, installed 0.9.8)
* responders (newest 3.0.1, installed 2.4.0)
* rspec-core (newest 3.9.2, installed 3.8.0)
* rspec-expectations (newest 3.9.2, installed 3.8.1)
* rspec-mocks (newest 3.9.1, installed 3.8.0)
* rspec-rails (newest 4.0.1, installed 3.8.0, requested ~> 3.8.0) in groups "development, test"
* rspec-support (newest 3.9.3, installed 3.8.0)
* rubyzip (newest 2.3.0, installed 1.2.1)
* safe_yaml (newest 1.0.5, installed 1.0.4)
* sass (newest 3.7.4, installed 3.4.23)
* sass-rails (newest 6.0.0, installed 5.0.6, requested ~> 5.0) in group "default"
* selenium-webdriver (newest 3.142.7, installed 3.6.0) in group "test"
* spring (newest 2.1.0, installed 2.0.1) in group "development"
* sprockets (newest 4.0.2, installed 3.7.1)
* sprockets-rails (newest 3.2.1, installed 3.2.0)
* sqlite3 (newest 1.4.2, installed 1.3.13) in group "default"
* thor (newest 1.0.1, installed 0.20.0)
* tilt (newest 2.0.10, installed 2.0.7)
* turbolinks (newest 5.2.1, installed 5.0.1, requested ~> 5) in group "default"
* turbolinks-source (newest 5.2.0, installed 5.0.0)
* tzinfo (newest 2.0.2, installed 1.2.5)
* uglifier (newest 4.2.0, installed 3.2.0) in group "default"
* vcr (newest 6.0.0, installed 3.0.3) in group "test"
* warden (newest 1.2.8, installed 1.2.7)
* web-console (newest 4.0.2, installed 3.5.0) in group "development"
* webmock (newest 3.8.3, installed 3.0.1) in group "test"
* websocket-driver (newest 0.7.2, installed 0.6.5)
* websocket-extensions (newest 0.1.5, installed 0.1.2)
* xpath (newest 3.2.0, installed 2.1.0)
悪夢のような数のgem
が。。。
ここで激しい勘違いをしていたのだが、in group development
とin group test
のものをまずアップデートしようと伊藤さんは言っているのであって、
それに該当するのが以下の表になるということらしい。
ちなみに、私はここから明後日の方向に進み出して、最終的に面倒になって、
全てのgem
のバージョン指定を解除した後にbundle update
をガツンとしたら、
RSpecで以下のようなエラーが出た。
There is a version mismatch between the Spring client (2.1.0) and the server (2.0.1).
〜 省略 〜
WARN Selenium [DEPRECATION] Selenium::WebDriver::Chrome#driver_path= is deprecated.
Use Selenium::WebDriver::Chrome::Service#driver_path= instead.
〜 省略 〜
なお、私はこのフェーズにおいて動画をほぼ見ずに作業をしていた。
動画は見ましょう、絶対に。
さて、最初から頑張ってみることにする。
4-a. 最新ではないgemを探す(第2チャレンジ)
ここまでの知見を生かし、Rubyのバージョン指定まで素早くこなす。
そして素直に、Gemfile
にbundle_outdated_formatter
を導入してみる。
指示どおりやっていくと、以下のとおりのエラーが出る。
これは動画でも紹介されているとおりである。
Resolving dependencies...
Bundler could not find compatible versions for gem "bundler":
In Gemfile:
rails (~> 5.1.1) was resolved to 5.1.1, which depends on
bundler (< 2.0, >= 1.3.0)
Current Bundler version:
bundler (2.1.4)
This Gemfile requires a different version of Bundler.
Perhaps you need to update Bundler by running `gem install bundler`?
Could not find gem 'bundler (< 2.0, >= 1.3.0)',
which is required by gem 'rails (~> 5.1.1)', in any of the sources.
ちなみに、これは先ほど試行錯誤していく中でも出たエラーである。
私は、エラーメッセージに従う形でbundlerのバージョンを下げたりして、
ゴニョゴニョやっていったが、伊藤さんによると「bundle update rails
ならいけるっぽい」
ということなので、ここはこのコマンドを試してみる。
やってみると、上手くアップデートできた。
動画では理屈について少し言及していたが、初学者なのでよく分からず。
ここで調べ出すとキリがなさそうなので、次のステップに行くことにした。
bundle outdated fomatter
のコマンドを使って取得した表は、開発環境・テスト環境下で
あるとかそのような状況に関係なく、全てのoutdated gems
を表示する。
そこで、動画の指示のとおり表計算ソフトで加工してみる。
手持ちのlibre office
で加工すると、以下のとおりの表となった。
何やら、伊藤さんのものと比べて、かなりシンプルなものになった。
4-b. development と test グループの gem を先にアップデートする
Gemfile
を開き、以下のgem
のバージョン指定を外してみる。
外すものは、動画で言及されていたものに限定した。
group :development, :test do
gem 'rspec-rails' # バージョン指定を解除
gem 'factory_bot_rails' # バージョン指定を解除
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end
group :test do
gem 'capybara' # バージョン指定を解除
gem 'selenium-webdriver' # バージョン指定を解除
gem 'chromedriver-helper'
# Or use poltergeist and PhantomJS as an alternative to Selenium/Chrome
# gem 'poltergeist', '~> 1.15.0'
gem 'launchy'
gem 'shoulda-matchers',
git: 'https://github.com/thoughtbot/shoulda-matchers.git',
branch: 'rails-5'
gem 'vcr'
gem 'webmock'
end
さて、以下を実行する。
bundle update -g development -g test
無事成功した。
ちなみに、動画ではchromedriver-helper
からwebdrivers
に移行するよう指示が出ていた。
詳細は動画のとおりだが、Gemfile
内のchromedriver-helper
をwebdrivers
に書き換えて、
bundle install
すればよいらしい。私の場合、bundle install
は問題なく実行できた。
さて、RSpecで再テストする。
何やら、エラーが色々と出てきた。
[DEPRECATED] `Bundler.with_clean_env` has been deprecated in favor of `Bundler.with_unbundled_env`.
If you instead want the environment before bundler was originally loaded, use `Bundler.with_original_env` (called at /Users/hogehoge/.rbenv/gems/2.4.0/gems/spring-2.0.1/lib/spring/application_manager.rb:95)
2020-06-17 18:31:22 WARN Selenium [DEPRECATION] Selenium::WebDriver::Chrome#driver_path= is deprecated. Use Selenium::WebDriver::Chrome::Service#driver_path= instead.
/Users/hogehoge/.rbenv/gems/2.4.0/gems/factory_bot-5.2.0/lib/factory_bot/definition_proxy.rb:99:in `method_missing': undefined method 'message' in 'note' factory
Did you mean? 'message { "My important note." }'
(NoMethodError)
〜 以下、省略 〜
この記事に詳細があるらしい。
動画で紹介されているとおり、まず以下を実行する。
gem install rubocop-rspec
そして、以下を実行する。
rubocop \
--require rubocop-rspec \
--only FactoryBot/AttributeDefinedStatically \
--auto-correct
〜 省略 〜
104 files inspected, 10 offenses detected, 10 offenses corrected
RSpecでテストする。
詳細は省略するが、以下の部分だけテストで失敗した。
Failures:
1) Tasks user toggles a task
Got 0 failures and 2 other errors:
1.1) Failure/Error: visit root_path
VCR::Errors::UnhandledHTTPRequestError:
1.2) Failure/Error: raise VCR::Errors::UnhandledHTTPRequestError.new(vcr_request)
VCR::Errors::UnhandledHTTPRequestError:
ただ、このFailuresは動画で紹介されているものである。
詳細は動画で確認してもらいたいが、以下のとおり設定すればテストでの失敗は回避できるらしい。
# spec/support/vcr.rb
VCR.configure do |config|
config.cassette_library_dir = "#{::Rails.root}/spec/cassettes"
config.hook_into :webmock
config.ignore_localhost = true
# 下記の config.ignore_hosts で始まる1行を追加
config.ignore_hosts 'chromedriver.storage.googleapis.com'
config.configure_rspec_metadata!
end
RSpecでテストする。
すると、何と全てのテストが通る!!!
Finished in 9.03 seconds (files took 1.11 seconds to load)
70 examples, 0 failures
どこまで進んだか
動画だと、前編の17分ぐらい経過したところまで進んだ。
続編はこちらは
【中編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita