LoginSignup
15
18

More than 3 years have passed since last update.

【前編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた

Last updated at Posted at 2020-06-18

はじめに

この記事は、タイトルのとおり、「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記事である。

永久保存版!?伊藤さん式・Railsアプリのアップグレード手順 - Qiita

この記事では、このアップグレード手順に準拠する形で章立てをする。

1. 公式のアップグレードガイドに目を通す

私はほぼ目を通しませんでしたが、通すと勉強になるかと思います。。。

2. テストが全部パスすることを確認する

動画では、テストが全てパスするか確認するよう指示が出ている。
RSpecでのテストは以下のコマンドで実行できる。

bin/rspec

Specテストでいきなりパスしない!

やってみると、下記の記事で紹介されているようなエラーが出た。

Everyday Railsのセットアップにて、masterブランチのテストを全てパスしたい

どうやら、Rubyのバージョンが問題であるようなので、大人しくRubyを2.4.9に指定することにした。
私は、Rbenvを使っているのだが、使い方を忘れているので、以下を参照して対応した。

Rubyのバージョン変更 - Qiita

# 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の話がベースだが、以下の記事を参考にした。

seleniumで「Message: session not created: This version of ChromeDriver only supports Chrome version 75」のエラーが表示される場合の対処法 - Qiita

どうやら、私が使っているChromeのバージョンとの不一致が問題である可能性が高い。
Chromeのバージョンを確認すると、以下のとおりバージョンが83だった。

Image from Gyazo

エラーメッセージを見直してみると、Everyday Railsの方ではバージョンが81を要求している。

ここでバージョンのダウングレードをしてもよいのだが、
そもそもRailsのバージョンを6にアップグレードした際に、
chromedriver-helperwebdriversに変更するよう指示が出ているので、
ここはスルーすることにする。

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 developmentin group test
のものをまずアップデートしようと伊藤さんは言っているのであって、
それに該当するのが以下の表になるということらしい。

Image from Gyazo

ちなみに、私はここから明後日の方向に進み出して、最終的に面倒になって、
全ての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のバージョン指定まで素早くこなす。

そして素直に、Gemfilebundle_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で加工すると、以下のとおりの表となった。

Image from Gyazo

何やら、伊藤さんのものと比べて、かなりシンプルなものになった。

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に移行するよう指示が出ていた。

サポートが終了したchromedriver-helperからwebdrivers gemに移行する手順 - Qiita

詳細は動画のとおりだが、Gemfile内のchromedriver-helperwebdriversに書き換えて、
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)

〜 以下、省略 〜

この記事に詳細があるらしい。

【翻訳】factory_bot 4.11で非推奨になった静的属性(static attributes) - Qiita

動画で紹介されているとおり、まず以下を実行する。

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

15
18
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
15
18