コードカバレッジは未使用のメソッドを強調しています-どうすればよいですか?


59

私は、既存のJavaプロジェクトのコードカバレッジを増やすように依頼されました。

コードカバレッジツール(EclEmma)が、どこからも呼び出されないメソッドを強調していることに気付きました。

私の最初の反応は、これらのメソッドの単体テストを書くことではなく、ラインマネージャー/チームにそれらを強調し、これらの機能がそもそもなぜあるのかを尋ねることです。

最善のアプローチは何でしょうか?それらの単体テストを作成するか、それらがなぜ存在するのか疑問に思いますか?


1
コメントは詳細なディスカッション用ではありません。この会話はチャットに移動さました
maple_shaft

回答:


118
  1. 削除します。
  2. コミット。
  3. 忘れる。

根拠:

  1. デッドコードはデッドです。まさにその説明によって、それは何の目的も持ちません。ある時点で目的を持っていたかもしれませんが、それはなくなっているので、コードはなくなるはずです。
  2. バージョン管理により、(私の経験では)誰かが後でそのコードを探しにやってくるまれなユニークなイベントで、それを取得できるようになります。
  3. 副作用として、何もせずにコードカバレッジを即座に改善します(デッドコードがテストされる場合を除きますが、これはめったにありません)。

コメントからの警告:元の答えは、コードが間違いなく死んでいることを徹底的に検証したと仮定していました。IDEには誤りがあり、実際には死んでいるように見えるコードが呼び出される可能性のある方法がいくつかあります確信がない限り、専門家を招いてください。


118
通常、このアプローチに同意しますが、プロジェクトやジュニア開発者が初めての場合は、削除する前にメンター/スーペリアに問い合わせてください。プロジェクトによっては、一部のメソッドが使用されていないように見える場合がありますが、アクセスできるプロジェクトコードではない外部コードによって呼び出されたり使用されたりします。自動生成されたコードである可能性があるため、削除してもログノイズが記録されるだけです。IDEは、プロジェクト内からリフレクションベースのアクセスを見つけることができない場合があります。Etc. pp。そのようなコーナーケースについてよくわからない場合は、少なくとも一度は尋ねてください。
フランクホプキンス

11
私はこの答えの核心には同意しますが、文字通りの質問は「なぜそこにあるのか疑問に思うべきですか?」でした。。この回答は、OPが削除する前にチームに尋ねるべきではないという印象を与える可能性があります。
ドックブラウン

58
ただし、最初にステップを追加します。未使用のコード行については、git blameログを確認してください。あなたがそれらを書いた人を見つけることができるならば、あなたは彼らが何のためにあるか尋ねることができます。行が新しい場合、誰かがすぐにそれらを使用することを計画している可能性があります(この場合、それらはおそらくユニットテストされるはずです)。
bdsl

10
コメントやその他の回答に示されているように、この回答には非常に多くの間違いがあり、これがトップの投票および承認された回答であるとは信じられません。
user949300

11
@Emory新しいチームで始める最善の方法は、不必要に削除することでビルドを壊すことです。1日目から人気があることを保証します(大規模で古いアプリケーションは常に100%のコードカバレッジの咳をするため)必要ないかもしれませんが、それは非常に悪いROIです。
Voo

55

他のすべての回答は、問題のメソッドが実際には使用されていないという仮定に基づいています。ただし、このプロジェクトは、このプロジェクトが自己完結型であるか、何らかのライブラリーであるかを指定しませんでした。

問題のプロジェクトがライブラリの場合、一見使用されていないメソッドがプロジェクトの外部で使用される可能性があり、それらを削除すると他のプロジェクトが破損します。ライブラリ自体が顧客に販売されているか、公開されている場合、これらの方法の使用を追跡することさえ不可能になる場合があります。

この場合、4つの可能性があります。

  • メソッドがプライベートまたはパッケージプライベートである場合、安全に削除できます。
  • メソッドが公開されている場合、機能の完全性のために、実際の使用方法がなくてもその存在が正当化される場合があります。ただし、テストする必要があります。
  • メソッドがパブリックで不要な場合、それらを削除すると重大な変更になり、ライブラリがセマンティックバージョニングに従う場合、これは新しいメジャーバージョンでのみ許可されます。
  • または、パブリックメソッドを非推奨にして、後で削除することもできます。これにより、APIコンシューマーが次のメジャーバージョンで削除される前に、廃止予定の関数から移行する時間が与えられます。

9
さらに、それがライブラリである場合、関数は完全性のためにそこにあります
-PlasmaHH

それらのテスト方法について詳しく説明していただけますか?メソッドが存在する理由がわからない場合は、おそらく何をすべきかわからないでしょう。
いいえU

filter_name_existsReloadSettingsまたはaddToSchema(3つの任意のオープンソースプロジェクトからランダムに選択された)のようなメソッド名は、メソッドが何をすべきかについてのヒントを提供する必要があります。javadocコメントはさらに便利です。適切な仕様ではありませんが、少なくともリグレッションを防ぐことができるいくつかのテストを作成するには十分かもしれません。
ゾルタン

1
プライベートクラスまたはインターフェイスのパブリックメソッドは、この目的のためにパブリックと見なされるべきではありません。同様に、パブリッククラスがプライベートクラス内にネストされている場合、実際にはパブリックではありません。
エモリー

30

まず、コードカバレッジツールが正しいことを確認します。

私は、インターフェースへの参照を介して呼び出されるメソッドで、またはクラスがどこかに動的にロードされる場合、それらがピックアップされない状況がありました。


どうもありがとう。Eclipseでは、関数のコードベースを検索しても何も表示されません。より包括的な検索を行う方法に関する他の提案がある場合は、私は最も感謝しています。
ルーカスT

3
はい、あなたは、DLLとして、クラスをインポートするかもしれない他のプロジェクトをチェックする必要があります
ユアン・

7
この答えは不完全だと感じています。「まず、コードカバレッジツールが正しいことを確認します。正しい場合は、... [残りの回答を挿入]」。具体的には、OP はコードカバレッジツールが正しい場合の対処方法を知りたいと考えてます。
ジョンベントレー

1
@jonbentley OPは、ツールレポートへの最適なアプローチを求めています。「それを手動で確認してください」その間違ったその文脈からそのかなり明白ので
ユアン・

15

Javaは静的にコンパイルされるため、メソッドを削除してもかなり安全です。デッドコードを削除することは常に良いことです。実行時にそれらを実行するクレイジーなリフレクションシステムが存在する可能性があるため、最初に他の開発者に確認してください。


9
人々とチェックするための+1、それは一種の最も驚きの少ない原則に従わない。誰かが以前にいくつかのコミットを残したばかりのメソッドを探すのに時間をかけすぎてほしくありません。また、いくつかのエッジケースでは、デッドコードが既にチェックインされているがまだどこにも配線されていない新しいものである場合があります(ただし、この場合、コメントで十分に文書化し、テストする必要があります)。
Frax

4
コードがリフレクションを使用して「未使用」メソッドを呼び出す場合を除きますが、その場合、はるかに大きな問題が発生します。クラス)。
MTilsted

2
静的にコンパイルされていますが、invokedynamic命令もあるので、知っています
...-corsiKa

@MTilsted:文字列を使用してコードを呼び出す多くのフレームワークがあります-少なくともSpringとHibernateは頭の中で思い浮かびます。
ジョミナル

9

最善のアプローチは何でしょうか?それらの単体テストを作成するか、それらがなぜ存在するのか疑問に思いますか?

コードを削除するのは良いことです。

コードを削除できない場合は、確実に@Deprecatedとしてマークし、メソッドを削除するためにターゲットにしているメジャーリリースを文書化できます。その後、「後で」削除できます。それまでは、それに依存する新しいコードを追加しないでください。

非推奨のメソッドに投資することはお勧めしません。カバレッジターゲットを達成するためだけの新しいユニットテストはありません。

2つの違いは主にメソッドが公開されたインターフェースの一部であるかどうかです。公開されたインターフェイスの一部を任意に削除すると、インターフェイスに依存していた消費者にとって不快な驚きになる可能性があります。

私はEclEmmaに話すことはできませんが、私の経験から、あなたが注意する必要があることの1つは反射です。たとえば、テキスト設定ファイルを使用して、アクセスするクラス/メソッドを選択する場合、使用/未使用の区別が明確でない場合があります(結合された時代に焼かれました)。

プロジェクトが依存関係グラフのリーフである場合、非推奨のケースは弱められます。プロジェクトがライブラリの場合、非推奨のケースはより強力です。

会社でmono-repoを使用している場合、複数レポの場合よりも削除のリスクが低くなります。

l0b0で述べたように、ソース管理でメソッドが既に利用可能な場合、削除後にメソッドを回復するのは簡単な作業です。本当にそうする必要があるか心配なら、必要に応じて削除された変更を回復できるようにコミットを整理する方法を考えてください。

不確実性が十分に高い場合は、コードを削除するのではなく、コメントアウトすることを検討できます。ハッピーパス(削除されたコードが復元されることはありません)での余分な作業ですが、復元が容易になります。私の推測では、それによって何回か焼かれるまでは、完全削除を好むはずです。これにより、このコンテキストで「不確実性」を評価する方法についての洞察が得られます。

なぜ彼らがそこにいるのか疑問?

伝承の獲得に費やされた時間は、必ずしも無駄ではありません。私は2つのステップで削除を実行することが知られています-最初に、コードについて学んだことを説明するコメントを追加してコミットし、その後コード(およびコメント)を削除します。

また、ソースコードで伝承をキャプチャする方法として、アーキテクチャ決定レコードに類似したものを使用することもできます。


9

コードカバレッジツールは、すべてを把握しているわけではありません。ツールがメソッドが呼び出されていないと主張しているからといって、メソッドが呼び出されていないわけではありません。リフレクションがあり、言語によってはメソッドを呼び出す他の方法があるかもしれません。CまたはC ++では、関数名またはメソッド名を構成するマクロが存在する場合があり、ツールが呼び出しを認識しない場合があります。したがって、最初のステップは次のとおりです。メソッド名および関連する名前をテキスト検索します。経験豊富な同僚に尋ねてください。実際に使用されている場合があります。

不明な場合は、各「未使用」メソッドの先頭にassert()を配置します。たぶん呼び出されます。またはロギングステートメント。

たぶん、コードは実際に貴重です。同僚が2週間作業を続けていて、明日は同僚が作業を開始する新しいコードかもしれません。明日は追加される予定なので、今日は呼び出されません。

たぶん、コードは実際に貴重なパート2です。コードは、物事がうまくいかないことを見つけることができる非常に高価なランタイムテストを実行している可能性があります。実際に問題が発生した場合にのみ、コードがオンになります。貴重なデバッグツールを削除している可能性があります。

興味深いことに、可能な限り最悪のアドバイス「削除、コミット、忘れて」。最高評価です。(コードレビューですか?コードレビューをしていませんか?コードレビューをしていない場合、一体何をプログラミングしていますか?)


「DELETE。COMMIT。FORGET」が最悪のアドバイスであることについて、私は敬意を持って同意しません。(最高だと思います。)。あなたのアプローチも大丈夫です。最悪のアドバイスは、「デッドコード」を実行するがアサーションを行わない単体テストを書くことだと思います。コードカバレッジツールは、だまされて使用されていると考えられます。
エモリー

3
"Delete。Commit。Forget"の回答には、コードレビューを行わないと言っているものはありません。コードがコミットされた後(ただし、展開前に:-))コードを確認することは完全に可能です(そして、私見することをお勧めします)
-sleske

@sleskeもう存在しないコードをどのようにレビューしますか?また、その回答は「レビュー」について言及していません。
user949300

@ user949300:コード変更のレビューが必要かどうかは別の質問であり、コードの追加、変更、削除とは無関係です(コードの追加は、削除よりもさらに悲惨なことがあります。Heartbleedの脆弱性などを参照してください)。さらに、(現在の)答えは「エキスパートを連れて行く」と言っており、コードレビューにかなり近いように聞こえます。
sleske

1
@ user949300:「もう存在しないコードをどのようにレビューしますか」に関して-私はそれが明白であることを願っています:選択したバージョン管理ツールの変更を見ること。他にどのような変更(変更)を検討しますか?
sleske

6

ソフトウェアが実行される環境に応じて、メソッドが呼び出されたかどうかを記録できます。適切な期間内に呼び出されない場合、メソッドは安全に削除できます。

これは、メソッドを削除するよりも慎重なアプローチであり、障害に敏感な環境で実行している場合に便利です。

#unreachable-code削除の候補ごとに一意の識別子を使用して専用のスラックチャネルにログを記録します。これは非常に効果的であることが証明されています。



「適切な期間」はより長いです(ただし、「真夜中の後の男」が好きですが)
ジェイミーブル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.