web-dev-qa-db-ja.com

Railsアプリで未使用のコードを見つける

実行中のコードと実行されていないコードを見つけるにはどうすればいいですか?生産中

アプリは十分にテストされていますが、unusedコードをテストする多くのテストがあります。したがって、テストを実行するときにカバレッジが得られます...この混乱をリファクタリングしてクリーンアップしたいのですが、それは私の時間を無駄にし続けています。私は多くのバックグラウンドジョブを持っています。これが私が本番環境で私をガイドしたい理由です。 herokuで実行すると、プロファイラーからのパフォーマンスへの影響を補正するためにdynoをスピンアップできます。

関連する質問 Rubyアプリで未使用のメソッドを見つけるにはどうすればよいですか? 役に立たない。

ボーナス:コードの行が実行される頻度を示すメトリック。なぜ私がそれを望むのか分からないが、私はそうする! :)

65
oma

通常の状況では、コードカバレッジにテストデータを使用するというアプローチになりますが、テストされているが本番アプリでは使用されていないコードの一部があると言うと、少し違うことをすることができます。

最初に明確にするために:自動ツールを信用しないでください。彼らはあなたが積極的にテストするものの結果のみを表示し、それ以上は表示しません。

私たちの背後にある免責事項を使用して、プロダクションアプリでコードカバレッジツール( rcov または simplecov のようなRuby 1.9)を使用し、コードパスを測定することを提案します実際にユーザーによって使用されます。これらのツールは元々テストカバレッジを測定するために設計されたものですが、本番カバレッジに使用することもできます

テスト期間中に関連するすべてのコードパスが訪問されるという仮定の下で、残りを削除できます。残念ながら、この仮定はおそらく完全には成り立たないでしょう。そのため、部品を削除するときは、アプリとその内部動作に関する知識を適用する必要があります。宣言的な部分(モデル参照など)を削除する場合、これらはしばしば直接実行されず、システムの他の部分の構成にのみ使用されるため、これはさらに重要です。

上記と組み合わせることができる別のアプローチは、アプリをリファクタリングして、オンとオフを切り替えることができる顕著な機能にしようとすることです。次に、使用されていないことが疑われる機能をオフにして、誰も文句を言わないかどうかを確認できます:)

最後に、完全な分析を行うための魔法のツールは見つかりません。これは、特定のコードが実際のユーザーによって使用されているかどうかをツールが認識できないためです。ツールでできることは(ある程度)静的到達可能性グラフを作成し、コードが特定のポイントから何らかの形で呼び出されたかどうかを知らせることだけです。 Rubyのような動的言語では、Railsコンテキストで頻繁に使用されるメタプログラミングや動的呼び出しに直面しても静的分析ではあまり洞察が得られないため、これを達成するのはかなり困難です。そのため、一部のツールは実際にコードを実行するか、テストカバレッジから洞察を得ようとします。しかし、魔法の呪文は絶対にありません。

Railsアプリケーションの内部(ほとんど隠されている)複雑さが高いため、ほとんどの分析を手作業で行うことはできません。おそらく、アプリをモジュール化し、特定のモジュールをオフにして、使用されていないことをテストすることをお勧めします。これは、適切な統合テストでサポートできます。

34
Holger Just

たぶん、Rails_best_practicesを使用して、未使用のメソッドとクラスをチェックすることができます。

これはgithubにあります: https://github.com/railsbp/Rails_best_practices .

Gemfileに 'gem "Rails_best_practices"'を入力して、Rails_best_practices .構成ファイルを生成する

21
big-circle

coverband gemをチェックアウトしてください。これは、まさにあなたが検索していることを実行します。

15

私は同じ問題を抱えていましたが、いくつかの代替案を検討した後、すぐに利用できるすべての情報、つまりログファイルがあることに気付きました。ログ形式は次のとおりです

Dec 18 03:10:41 ip-xx-xx-xx-xx appname-p[7776]:   Processing by MyController#show as HTML

そこで、この情報を解析する簡単なスクリプトを作成しました

zfgrep Processing production.log*.gz |awk '{print $8}' > ~/tmp/action

sort  ~/tmp/action | uniq -c |sort -g -r > ~/tmp/histogram

特定のcontroller#actionがアクセスされた頻度の結果を生成します。

4394886 MyController#index
3237203 MyController#show
1644765 MyController#edit

次のステップは、アプリ内のすべてのcontroller#actionペアのリストと比較することです(rake routes出力を使用するか、スイートをテストするために同じスクリプトを実行できます)

13
katzmopolitan

疑わしいメソッドをプライベートとしてマークするというアイデアはすでに得られています(アプリケーションを破壊する可能性がある)。

過去に行った小さなバリエーション:すべての不審なメソッドに小さなコードを追加してログに記録します。私の場合、「古い関数を呼び出しました-本当に必要な場合はITに連絡してください」というユーザーポップアップでした。 1年後、実際に使用されたものの概要がわかりました(ビジネスアプリケーションであり、機能が1年に1回だけ必要でした)。

あなたの場合、使用量のみを記録する必要があります。妥当な期間が経過してもログに記録されないものはすべて使用されません。

4
knut

私はRubyとRoRにはあまり詳しくありませんが、私がおかしな推測を提案するものは:

  • 追加 :after_filter以前に呼び出されたメソッドの名前をログに記録する(コールスタックから取得する)ファイルに
  • これを本番に展開します
  • しばらく待つ
  • ログにないすべてのメソッドを削除します。

追伸おそらく、NetBeansまたはRubyMineでAlt + F7を使用したソリューションの方がはるかに優れています:)

4
alex.b

メタプログラミング

Object#method_missing

Object#method_missingをオーバーライドします。内部では、呼び出し元のClassおよびmethodを非同期的にデータストアに記録します。次に、method_missingに渡された引数に基づいて、適切な引数を使用して元のメソッドを手動で呼び出します。

オブジェクトツリー

次に、データストア内のデータをアプリケーションのオブジェクトツリーのコンテンツと比較します。

免責事項:これは確かにかなりのパフォーマンスとリソースの考慮を必要とします。また、それを機能させるには少し手を加える必要がありますが、理論的には機能するはずです。それ。;)

3

sahi のようなものを使用してテストスイートを作成してみましたか?これを使用してすべてのユーザージャーニーを記録し、それらのテストをrcovまたは同様のものに結び付けることができます。

すべてのユーザージャーニーがいることを確認する必要がありますが、その後、rcovが吐き出すものを確認し、少なくともカバーされていないものを除去することを開始できます。

1
krystan honour

これはあまり積極的なアプローチではありませんが、 New Relic から収集された結果を使用して、未使用であると疑われるものが過去1か月ほどの間に本番で呼び出されたかどうかを確認しました。私がこれを使ったアプリはかなり小さいものでしたが、大きなアプリケーションにはかなり高価です。

私は自分で使ったことはありませんが、 この投稿レーザー宝石 については、あなたの正確な問題を解決することについて話しているようです。

1
Chris

不審なメソッドをプライベートとしてマークします。コードが中断しない場合は、メソッドがクラス内で使用されているかどうかを確認してください。その後、あなたは物を削除することができます

0
Dirk de Kok

これは完璧な解決策ではありませんが、たとえばNetBeansでは、メソッドを右クリックして(またはAlt + F7を押して)メソッドの使用法を見つけることができます。
したがって、メソッドが使用されていない場合は、表示されます。

0
beornborn