Railsアプリのテスト実行時に特定の警告だけを例外に変換する

今後役立つのかわからないがRuby 2.7→3.xアップデートのときに使った方法のメモ。

Warning[:deprecated] = true すると表示される非推奨警告を発生させるコードがRailsアプリに含まれないように、テスト実行時だけこのような警告をあらかじめエラーに変換できると検出しやすくて便利。また、特定の警告(たとえばキーワード引数分離など)だけエラーにしたいという状況がありうる。jeremyevans/ruby-warningを使うことで、このような警告のハンドリングを実現できる。

RSpecのテストがある場合、spec/rails_helper.rbの最初のほうに次のようなコードを書いておく。

# spec/rails_helper.rb
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'

require 'warning'

# 1. 非推奨警告を出力する
Warning[:deprecated] = true

# 2. Railsアプリにキーワード引数分離に関する警告が含まれるとき例外を上げる
Warning.process(File.expand_path("..", __dir__), keyword_separation: :raise)

# 3. Warningの設定後にアプリと依存しているgemをロードする
require_relative '../config/environment'

まず、1のように非推奨警告を表示するようにRubyのレベルで設定しておく。その後、ruby-warning gemによって追加されるWarning#processを通じて、2のように親ディレクトリ(アプリのルートディレクトリ)配下のコードでキーワード引数分離(:keyword_separation)の警告が発生したら例外を発生(:raise)させる。ここで指定できる警告とハンドリングの種類についてはruby-warning gemのREADMEに説明がある。

https://github.com/jeremyevans/ruby-warning#label-Usage+

以上の設定は、3のようにアプリ自体のコードをロードする前に実行しておく必要がある。

参考

約8年開発されている Rails 製プロダクトを Ruby 3 にバージョンアップするために keyword parameters is deprecated を「網羅的に」検知する方法 - Money Forward Developers Blog