Rails 4.x -> 5.x に上げた後 cap deploy できない（解決済み）

# 先に結論

`lib/task/` 下にテスト関連の rakefile を置く場合、Rails5 からは以下のように `require 'rake/task'` を各ファイルに記載する必要があるようです。

```ruby
# 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 系にアップグレードしておかないとこの先マズいな、と思ったので、夏休みを利用して以下の順にアップグレードしました。

1. Rails 4.2.9 => 4.2.10
2. Rails 4.2.10 => 5.0.7
3. Rails 5.0.7 => 5.1.6
4. Rails 5.1.6 => 5.2.1

作業そのものも色々ありましたが、とりあえず上記の作業は 4日くらいで終了し、いざ本番環境に展開しようと `cap deploy` したところエラーになりました。`log/capistrano.log` を参照したところ以下の記録が。

```ruby
# 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` 絡みで起きていることは分かりました。この時点では

1. `rake assets:precompile` でコケている
2. Capistrano を使い始めたときにもここで良くハマった苦い思い出が…
3. 取り敢えず `rake assets:precompile` を無効にしてみるか

と考え、ググって無効化してみたものの、次の `rake` タスクで同じエラーでストップしてしまいました。ここまでに「あーでもない、こーでもない」と 30分くらい浪費した気がします。

## `rake` の問題？

そこで手抜きを諦めて、`rake` 絡みで再度ググってみました。キーワードは[『capistrano assets:precompile NameError: uninitialized constant Rake::TestTask』](http://bit.ly/2zAq0Lq)。

ヒットしたコンテンツをざっと眺めてみたものの、自分の状況と一致するものがありません（と勘違いしていました）。段々、疑心暗鬼になってしまい、

* `capistrano3 gem` のバージョン違いで何かあるのか？
* Rails 4.x -> 5.x に上げる過程で何か漏れがあったのか？
* 今日は厄日か？

と色々考えてみたのですが、起きている症状は明らかに `rake` 絡みです。そこでもう一度、検索結果を一つずつ見てみたところ [[master] NameError: uninitialized constant Rake::TestTask #19997] (https://github.com/rails/rails/issues/19997#issuecomment-98552320) に説明されていることが該当するのに気づきました。

```
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 にアップグレードしたことで引っかかってしまったのだと思います。

ということで

```ruby:lib/tasks/test_lib_dir.rake
# 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](http://app.wercker.com/) を使って CI してるし… と思っていたのですが、デプロイのテストも必要なんですね、やっぱり。

ということで、ステージング環境を作ります…