#252 Metrics Metrics Metrics
メトリクスは、コードを評価して改善すべき箇所を見つける方法を提供します。metric_fuは、エピソード166[動画を見る, 読む]で紹介した、Ruby向けの優れたメトリクス計測ツールです。ただ問題は、依存関係が複雑なためセットアップが少し難しく、Rails 3で使用する場合は特にそうです。代わりに利用されたのがthe Caliper projectでした。Githubリポジトリに接続してメトリクス計測を行うことができましたが、残念ながら今は公開されていません。
そこで、やはりローカル環境で計測を実行することにして、それを簡単におこなえるMetricalというgemを紹介します。Metricalはバックグラウンドでmetric_fuを利用しながら、簡単に操作できるラッパーコマンドを提供します。
Railscastsのサイトのソースコードに対して計測を行うことでMetricalを実際に試してみましょう。まずMetrical gemをインストールします。
$ gem install metrical
このgemをインストールすると、依存しているいくつかのgemも同時にインストールされます。それらがすべてインストールされると、アプリケーションのディレクトリからmetrical
コマンドを実行できるようになります。このコマンドで、metric_fuを介してアプリケーションのコードに対していくつかの計測が実行されます。出力結果にいくつかのエラーが含まれているかも知れませんが、コマンドが終了したのであればそれらを無視しても特に問題はないでしょう。正常に終了したかどうかは、結果をブラウザで見てみればわかります。
最初のページにはmetric_fuが実行した計測ツール群がリストアップされています。任意の行をクリックすると、生成された計測結果が表示されます。例えば、Reek を見てみるとアプリケーションの改善すべき部分についての有用なフィードバックを得ることができます。
次にもうひとつ、Rcovというツールを見てみましょう。Metricalで実行されるツールの内、Rcovはアプリケーションのtestとspecを実行する必要があるため、失敗する確率がもっとも高いでしょう。Railscastsのコードに対して実行した場合、カバー率は0.0%になります。ここで一番大きな問題は、RcovがまだサポートしていないRuby 1.9のコードが使われていることです。代わりとなるものを調べる前にツール群からRcovをはずしておきます。Metricalから操作する場合のmetric_fuの動作を設定ためには、アプリケーションのルートディレクトリに.metrics
ファイルを追加します。
MetricFu::Configuration.run do |config| config.metrics -= [:rcov] end
再度metrical
を実行してみると、エラー数が減って、Rcovが結果に表示されていません。しかしコードカバー率は有用な計測値です。Rcovの代わりに何を使えばいいでしょう?いくつかの代替ツールがあります。例えば、CoverMeとSimpleCovです。どちらも有用な結果を生成してくれますが、今回は設定が簡単なSimpleCovを選択します。まずアプリケーションのGemfile
にgemの情報を追加します。
group :test do gem 'simplecov', '>=0.3.8', :require => false end
次にテストやスペックのヘルパーファイルに次の2行を追加します。
require 'simplecov' SimpleCov.start 'rails'
いつもと同じく、アプリケーションにgemを追加する場合はbundle
を実行してgemがインストールされたことを確認します。インストール後、rake spec
コマンドでアプリケーションのスペックを実行し、coverage/index.html
を開いて結果を確認します。
これによって、テストやスペックでのコードのカバー率が低いファイルを簡単に見つけることができます。カバー率がもっとも低いファイルから順に表示されています。例としてcomments_controller
をクリックすると、具体的にどのコードがカバーされていてどれがされていないかを見ることができます。
これを使ってどのコードがカバーされていないかを特定でき、テストかコードのいずれかを修正してカバー率を改善します。
コードのカバー率についてはこれで解決です。続いてmetric_fuが提供する新しい2つの計測ツール、The Best Practices ReportとHotspotsを見てみましょう。
Hotspotsはアプリケーション内のファイル、クラス、メソッドの概要を一覧で表示し、もっとも悪いものから順に並べて示します。もっとも悪いものを決めるのにはいくつかの要因が考慮されますが、基本的にはReekとFlogを見ます。Hotspotsはまず最初にチェックする場所として適しているでしょう。そこからアプリケーションの考慮すべき箇所を順にチェックしていくことができます。
The Rails Best Practicesはアプリケーション内でベストプラクティスに合致しない箇所を教えてくれます。
このレポートの出力はブラウザで見ると少し見にくいので、metric_fuからではなく直接実行してみましょう。すでにMetricalをインストールしてあるのでgemが存在するはずですが、もしなければ以下を実行します。
$ gem install rails_best_practices
このコマンドを実行すると、出力結果の中にRails Best Practicesのサイトを参照するよう指示が表示されるので、サイトを見てみることにしましょう。
Rails Best Practicesには多数のベストプラクティスが掲載されています。読んで参考にしたり、アプリケーションに適用して改善することができます。「適用済み(Implemented)」タブで表示される項目はgemによって使用されているもので、rails_best_practices
コマンドを実行するとチェックされます。
このコマンドを実行すると、複数の提案が赤字で表示されます。
$ rails_best_practices Analyzing: 100% |oooooooooooooooooooooooooooooooooooooooooo| Time: 00:00:00 <span style="color:#C00;">./app/controllers/comments_controller.rb:53 - move model logic into model (errors use_count > 4) ./app/views/comments/index.rss.builder:10 - law of demeter ./app/views/comments/index.rss.builder:10 - law of demeter ./db/schema.rb:15 - always add db index (comments => [user_id]) ./db/schema.rb:71 - always add db index (spam_reports => [comment_id]) ./app/controllers/comments_controller.rb:28,32,41 - use before_filter for edit,update,destroy ...</span>
赤字のテキストはあまり目によくないかもしれません。代わりに出力形式としてHTMLを指定でき、さらにオプションを追加することでファイル名にリンクをつけTextMateで対応するファイルが開くよう指定します。
$ rails_best_practices -f html --with-textmate
これによってrails_best_practices.html
というHTMLファイルが生成され、ブラウザで開けるようになります。
このアプリケーションでは26のエラーが検出されました。ファイル名をクリックすると、そのファイルがTextMateで開きます。エラーメッセージをクリックすると、Rails Best Practicesサイトの対応するページが表示され、問題の説明とコードを改善する方法を読むことができます。あとはリストのアイテムをひとつずつ潰してコードを改善するだけです。
他の計測結果にも言えることですが、推奨された内容を鵜呑みにしないようにしましょう。ある手法が一般的にベストプラクティスであると見なされていても、それが自分のアプリケーションにとってもベストであるとは限りません。生成されたリストは、改善できる可能性がある箇所を見つけるための一般的なガイドラインであると受け止める方がいいでしょう。リストの項目をゼロに減らすのを目的にするべきではありません。これは他のすべての計測項目にも言えることです。表示された改善提案が自分のアプリケーションにとって本当にベストかを常に考えてから適用し、アプリケーションのコードが本当に改善されたことを確認するようにすべきです。メトリクスは、コードをどう改善するかのヒントとして利用するのがいいでしょう。