問題解決へのプロセスにもなる気がするので後輩向けに残す。
起こった事
Ruby on Rails チュートリアル
「3.3.2 Red」はわざとテストを失敗させる場所なのだが、出力がチュートリアルの想定と違う。
(1/22時点で最新パッケージを取ると発生)
$ rails test
3 tests, 2 assertions, 0 failures, 1 errors, 0 skips
これなら納得なのだが。
miihonani:~/workspace/sample_app (static-pages) $ rails t
Running via Spring preloader in process 3875
/home/ubuntu/workspace/sample_app/db/schema.rb doesn't exist yet. Run `rails db:migrate` to create it, then try again. If you do not intend to use a database, you should instead alter /home/ubuntu/workspace/sample_app/config/application.rb to limit the frameworks that will be loaded.
Run options: --seed 32996
# Running:
Run options: --seed 32996
# Running:
EE
Error:
StaticPagesControllerTest#test_should_get_about:
NameError: undefined local variable or method `static_pages_about_url' for #<StaticPagesControllerTest:0x000000036734c0>
test/controllers/static_pages_controller_test.rb:15:in `block in <class:StaticPagesControllerTest>'
/usr/local/rvm/gems/ruby-2.4.0/gems/railties-5.1.4/lib/rails/test_unit/reporter.rb:70:in `method': undefined method `test_should_get_about' for class `Minitest::Result' (NameError)
from /usr/local/rvm/gems/ruby-2.4.0/gems/railties-5.1.4/lib/rails/test_unit/reporter.rb:70:in `format_rerun_snippet'
(中略)
2.4.0/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from -e:1:in `<main>'
方々でバグを踏んだ経験から直感的に「これアカン奴」と気づいたけど、初学者がいきなり引いても訳が分からないやつなのではないでしょうかコレ。
解消プロセス
片っ端から検索する
「rails チュートリアル 3章 失敗」でググる
さすがに出てこない
「/usr/local/rvm/gems/ruby-2.4.0/gems/railties-5.1.4/lib/rails/test_unit/reporter.rb:70:in(=エラーメッセージ)」でググる
前日(1/22)にteratailで質問された内容が出てきた。チュートリアルこそ違うがたぶん状況は同じ。回答欄のリンクで「プロを目指す人のためのRuby入門」でテスト失敗時に実行結果が正常に表示されない場合を案内されているので、読む。
だいたい原因は分かった。とりあえずminitestの最新版とrailtiesの相性が悪いらしい。この業界にはよくある話だと思いつつ、初学者にそれを察するすべはあるのかしらと考える。たぶん無理。
で、私的にはここで終わらずもう少し掘る。
###「minitest rails チュートリアル」で検索
ちょっと下のほうに潜ったら出てきた。
Railsチュートリアルの「3.3.1 最初のテスト」のテストをエラーになる
実際は「3.3.2 Red」で発生しているけど、まぁ以前からあったということで納得。この人はminitestのバージョンを落として解消している。
解消方法
minitestのバージョンを落とせばいい、ということでgemfileに以下を追加。
(前後略)
group :test do
gem 'rails-controller-testing', '1.0.2'
gem 'minitest-reporters', '1.1.14'
gem 'guard', '2.13.0'
gem 'guard-minitest', '2.4.4'
gem 'minitest', '~> 5.10.1' # 最新の5.11.1だとrailtiesと相性が悪い
end
原因として5.11.0~5.11.1でエラーが出ることは記述があったのと、最後サイトののgemの書き方(gem 'minitest', '~> 5.10', '!= 5.10.2')だと5.11を取るのでとりあえずこう書いておきます。
この書き方だと5.10.XのX最大値を取ってくる形、最終的に5.10.3で問題がないことを確認。
miihonani:~/workspace/sample_app (static-pages) $ bundle update
(前後略)
Fetching minitest 5.10.3 (was 5.10.1)
Installing minitest 5.10.3 (was 5.10.1)
(略)
miihonani:~/workspace/sample_app (static-pages) $ rails t
Running via Spring preloader in process 4336
(略)
Finished in 0.711300s, 4.2176 runs/s, 2.8118 assertions/s.
3 runs, 2 assertions, 0 failures, 1 errors, 0 skips
というわけで(たぶん)これがチュートリアルの想定解になると思います。
私的メモ
プログラミング絡みで大抵のことは先人が既に通った問題だと思うので、想像できる限り調べる。その筋の想像力は経験で身に付く。
追記(04/13/2018)
rails側の問題のため、チュートリアルがgemで5.1.4固定にしている限りはminitestは5.10.X系にする必要があります。
現状ではRailsも5.1.5以降が出ておりそちらではfixされているため、解決策は以下の2パターンになっています。
・railsを5.1.5以降に上げる→minitestは最新を取っても良い (ただし別のところで問題が発生する可能性はある)
・railsを維持する→minitestを5.10.X系にする
私見としては本当に初めて触る人はrails側を固定した方がいいと思いますが、別の祖語が発生しても勉強だと開き直れる人はrailsを上げるとよいでしょう。