Rails: アプリケーションを静的解析で"防弾"する3つの便利ワザ(翻訳)
静的解析とは、コードを実行せずに潜在的な問題を特定して品質を改善することです。有用な静的解析手法を導入することで、アプリケーションの信頼性を高められます。本記事では、コードベースの問題を静的解析で解決するうえで便利な手法を3つ解説します。
🔗 1: ファイル名が間違っているテストファイルを検出する
先頃、顧客のアプリケーションに含まれている未使用のコードを追いかけていたときに、明らかにパスしないRSpecテストが1つ見つかりました。rspec
でパスを指定してこのテストだけを実行してみると、やはり失敗しました。
しかしbundle exec rspec
でテストスイートを実行するとテストがすべてパスしてしまいます。さらに調べてみると、このテストファイルがRSpecの命名規則に沿っていないことが判明しました。
RSpecのドキュメントには以下のように書かれています。
# デフォルト: すべてのspecファイルを実行する(spec/**/*_spec.rbにマッチするファイルが対象)
$ bundle exec rspec
RSpecでバイパスされるテストファイルが他にもあるかどうかを検証したかったのですが、プロジェクトが巨大なため手動で調べるのは無理でした。
そこで以下のコマンドを使うことで、問題のあるテストファイルを残らず特定できました。
find ./spec -type f -not -name \*_spec.rb -not -path "./spec/factories/*" -not -path "./spec/support/*" | xargs rg RSpec\.describe
調べた結果、*.spec.rb
や*_sepc.rb
といったファイルの命名ミスが続々見つかりました。これらのテストファイルを正しくリネームすると、それらの半分近くが失敗していたことが判明しました。
🔗 2: 解決しない定数を検出する
参考: Tracking down not resolving constants in Ruby with parser | Arkency Blog
上の過去記事で、解決しない定数をparser
gemで追跡する方法を詳しく解説しました。解決されない定数は実行時エラーになる可能性がありますが、静的解析で手軽に防止できます。このスクリプトは以下のリポジトリで公開しているので、このcollector.rbを自分のプロジェクトにコピーすれば、以下のように簡単に実行できます。
bundle exec ruby collector.rb app/
🔗 3: 不要なルーティングを検出する
コードベースをきれいにする便利なスクリプトをもうひとつご紹介します。
このスクリプトは、routes.rbファイル内で定義されているルーティングの中に、対応するコントローラアクションが存在しないものや、暗黙のレンダリング用のビューが存在しないものがあるかどうかをチェックします。
# unused_routes.rb
require_relative "config/environment"
Rails.application.routes.routes.map(&:requirements).each do |route|
next if route.blank?
next if route[:internal]
controller_name = "#{route[:controller].camelcase}Controller"
next if controller_name.constantize.new.respond_to?(route[:action])
implicit_render_view = Rails.root.join("app", "views", *route[:controller].split('::'), "#{route[:action]}.*")
next if Dir.glob(implicit_render_view).any?
puts "#{controller_name}##{route[:action]}"
rescue NameError, LoadError
puts "#{controller_name}##{route[:action]} - controller not found"
end
このスクリプトをコピーしてruby unused_routes.rb
を実行するだけでチェックできます。もしかすると凄い結果が表示されるかもしれません。
訳注
参考: 現在のRailsのmainリポジトリには、bin/rails routes --unused
で未使用のルーティングを検出する機能がマージされています(#45701)。おそらくRails 7.1から利用できると思われます。
元記事末尾のフォームに登録いただくと、Arkencyのベテランプログラマーによる磨き抜かれた洞察や知恵を結晶したメールマガジンを配信いたします。
概要
元サイトの許諾を得て翻訳・公開いたします。
日本語タイトルは内容に即したものにしました。