先に結論
lib/task/
下にテスト関連の rakefile を置く場合、Rails5 からは以下のように require 'rake/task'
を各ファイルに記載する必要があるようです。
# coding: utf-8
require 'rake/testtask'
namespace :test do
desc "Test lib source"
Rake::TestTask.new(:lib) do |t|
t.libs << "test"
t.pattern = 'test/lib/**/*_test.rb'
t.verbose = true
end
end
起きたこと
Rails 4.2.9 の社内用システムがあり、いい加減 Rails 5 系にアップグレードしておかないとこの先マズいな、と思ったので、夏休みを利用して以下の順にアップグレードしました。
- Rails 4.2.9 => 4.2.10
- Rails 4.2.10 => 5.0.7
- Rails 5.0.7 => 5.1.6
- Rails 5.1.6 => 5.2.1
作業そのものも色々ありましたが、とりあえず上記の作業は 4日くらいで終了し、いざ本番環境に展開しようと cap deploy
したところエラーになりました。log/capistrano.log
を参照したところ以下の記録が。
# Logfile created on 2018-09-27 18:28:37 +0900 by logger.rb/61378
INFO ---------------------------------------------------------------------------
INFO START 2018-09-27 18:28:37 +0900 cap production deploy
INFO ---------------------------------------------------------------------------
INFO [1f0dd9de] Running /usr/bin/env mkdir -p /tmp as mikoshi@flower.example.co.jp
(省略)
INFO [e3236158] Running bundle exec rake assets:precompile as mikoshi@flower.example.co.jp
DEBUG [e3236158] Command: cd /var/rails/mikoshi/releases/20180927092841 && ( export PATH="/usr/local/rubys/2.5.1/bin:/bin:/usr/bin:/usr/local/bin" RAILS_ENV="production" ; bundle exec rake assets:precompile )
DEBUG [449ec255] rake aborted!
NameError: uninitialized constant Rake::TestTask
DEBUG [449ec255] /var/rails/mikoshi/shared/bundle/ruby/2.5.0/gems/bootsnap-1.3.2/lib/bootsnap/load_path_cache/core_ext/active_support.rb:74:in `block in load_missing_constant'
/var/rails/mikoshi/shared/bundle/ruby/2.5.0/gems/bootsnap-1.3.2/lib/bootsnap/load_path_cache/core_ext/active_support.rb:8:in `without_bootsnap_cache'
/var/rails/mikoshi/shared/bundle/ruby/2.5.0/gems/bootsnap-1.3.2/lib/bootsnap/load_path_cache/core_ext/active_support.rb:74:in `rescue in load_missing_constant'
/var/rails/mikoshi/shared/bundle/ruby/2.5.0/gems/bootsnap-1.3.2/lib/bootsnap/load_path_cache/core_ext/active_support.rb:56:in `load_missing_constant'
/var/rails/mikoshi/releases/20180927092841/lib/tasks/test_lib_dir.rake:4:in `block in <main>'
/var/rails/mikoshi/releases/20180927092841/lib/tasks/test_lib_dir.rake:1:in `<main>'
解決に至る道筋
タスク assets:precompile
の問題?
Rake::TestTask
が未定義とあるのですが、勿論 cap deploy
過程でテストするわけもなく、rake
絡みで起きていることは分かりました。この時点では
-
rake assets:precompile
でコケている - Capistrano を使い始めたときにもここで良くハマった苦い思い出が…
- 取り敢えず
rake assets:precompile
を無効にしてみるか
と考え、ググって無効化してみたものの、次の rake
タスクで同じエラーでストップしてしまいました。ここまでに「あーでもない、こーでもない」と 30分くらい浪費した気がします。
rake
の問題?
そこで手抜きを諦めて、rake
絡みで再度ググってみました。キーワードは『capistrano assets:precompile NameError: uninitialized constant Rake::TestTask』。
ヒットしたコンテンツをざっと眺めてみたものの、自分の状況と一致するものがありません(と勘違いしていました)。段々、疑心暗鬼になってしまい、
-
capistrano3 gem
のバージョン違いで何かあるのか? - Rails 4.x -> 5.x に上げる過程で何か漏れがあったのか?
- 今日は厄日か?
と色々考えてみたのですが、起きている症状は明らかに rake
絡みです。そこでもう一度、検索結果を一つずつ見てみたところ [master] NameError: uninitialized constant Rake::TestTask #19997 に説明されていることが該当するのに気づきました。
It is not a regression. I know that rails is not requiring
Rake::TestTask anymore in master but this is because we don't
need it anymore.
What I said is: You are expecting Rails to require Rake::TestTask
when you should not. If you want to use that in your own rake files
you should require it.
アリがちですが test/lib/
以下に Minitest
のテストケース用ファイルを置いて、それを rake test:lib
でテストできるように Rails4 の時代に lib/task/test_lib_dir.rake
というファイルを作っていました。これが Rails5 にアップグレードしたことで引っかかってしまったのだと思います。
ということで
# coding: utf-8
require 'rake/testtask'
namespace :test do
desc "Test lib source"
Rake::TestTask.new(:lib) do |t|
t.libs << "test"
t.pattern = 'test/lib/**/*_test.rb'
t.verbose = true
end
end
に修正して git commit && git push
した後、cap deploy
したところ、無事に正常終了しました。
教訓
このシステムはバックエンドに LDAP(OpenLDAP)を使っていることもあり、ステージング環境を作るのが面倒で、本番環境しかありませんでした。小さなシステムだし、wercker を使って CI してるし… と思っていたのですが、デプロイのテストも必要なんですね、やっぱり。
ということで、ステージング環境を作ります…