32

コードカバレッジのいくつかの悪い副作用の実例を探しています。

私は最近、100%のコードカバレッジを達成するためのポリシーのために、これが職場で起こっていることに気づきました。コードの品質は確かに向上していますが、逆に、「コードは完全に単体テストされている」ため、テスターはより緩いテスト計画を作成しているようです。その結果、いくつかの論理的なバグがすり抜けることができました。「コードは完全に単体テストされている」ため、デバッグには非常に大きな苦痛がありました。

これは、私たちのツールがステートメントカバレッジのみを行ったことが一因だと思います。それでも、もっとよく過ごした時間だったかもしれません。

コードカバレッジポリシーを持つことによる他のマイナスの副作用がある場合は、共有してください。現実の世界で他にどのような「問題」が起こっているのか知りたいのですが。

前もって感謝します。

編集:すべての本当に良い応答をありがとう。答えとしてマークするものはいくつかありますが、残念ながら1つしかマークできません。

4

13 に答える 13

59

一言で言えば: コード カバレッジは、何を持っているかではなく、何をテストしていないかを明らかにします

価値のある単体テスト スイートを構築することの一部は、最も重要でリスクの高いコードを見つけて、それについて難しい質問をすることです。タフなものが優先的に機能することを確認したい. カバレッジの数値には、コードの「重要性」やテストの品質に関する概念はありません。

私の経験では、これまでに作成した最も重要なテストの多くは、カバレッジをほとんど追加しないテストです (あちこちで数 % 余分に追加するが、大量のバグを見つけるエッジ ケース)。

厳しい (潜在的に非生産的な) カバレッジ ターゲットを設定することの問題点は、開発者がコードをテストするために後ろ向きに曲げ始める必要がある場合があることです。コードをテスト可能にすることはありますが、そこにはただの拷問があります。優れたテストで 100% のカバレッジに達した場合、それは素晴らしいことですが、ほとんどの場合、余分な労力を費やす価値はありません。

さらに、人々はテストの質に注目するのではなく、数字に執着したりいじったりし始めます。カバー率が 60 ~ 70% しかない優れたテストを見たのと同じように、90% 以上のカバー率を持つ下手に書かれたテストを見てきました。

繰り返しになりますが、私はカバレッジを、何がテストされていないかを示す指標と見なす傾向があります。

于 2009-03-30T03:02:40.673 に答える
19

コード カバレッジがあるからといって、関数を介してすべてのパスを実際にテストしているとは限りません。

たとえば、次のコードには 4 つのパスがあります。

if (A) { ... } else { ... }
if (B) { ... } else { ... }

ただし、2 つのテスト (たとえば、A と B が true のテスト、A と B が false のテスト) だけで、「100% のコード カバレッジ」が得られます。

魔法の 100% の数値を達成すると、テストをやめる傾向があるため、これは問題です。

于 2009-03-30T02:21:08.263 に答える
19

私の経験では、コード カバレッジ ツールの最大の問題は、「高いコード カバレッジ」が「優れたテスト」に等しいという考えの犠牲になるリスクです。ほとんどのカバレッジ ツールは、条件、データ パス、または決定カバレッジとは対照的に、ステートメント カバレッジ メトリックを提供するだけです。これは、次のようなコードで 100% のカバレッジを得ることができることを意味します。

for (int i = 0; i < MAX_RETRIES; ++i) {
    if (someFunction() == MAGIC_NUMBER) {
        break;
    }
}

... for ループで終了条件をテストすることなく。

さらに悪いことに、アプリケーションを呼び出すだけのテストから、出力を検証したり、誤って検証したりすることなく、非常に高い「カバレッジ」を得ることができます。

簡単に言えば、コード カバレッジ レベルが低いことは確かにテストが不十分であることを示していますが、カバレッジ レベルが高いことは、テストが十分または正しいことを示しているわけではありません。

于 2009-03-30T02:28:21.443 に答える
5

コーナーケースが非常にまれで、テストする価値がない場合もありますが、厳密なコードカバレッジルールでは、とにかくテストする必要があります。

たとえば、JavaにはMD5アルゴリズムが組み込まれていますが、技術的には「サポートされていないアルゴリズム」タイプの例外がスローされる可能性があります。それは決して投げられず、あなたのテストはその道をテストするためにかなりの旋回を経なければならないでしょう。

それは多くの無駄な仕事になるでしょう。

于 2009-03-30T02:18:38.207 に答える
5

私の意見では、チームがコード カバレッジを測定することから逃れる最大の危険は、大規模なテストに報酬を与え、小規模なテストに不利になることです。アプリケーションの機能の大部分をカバーする 1 つのテストを作成するか、1 つのメソッドをテストする 10 個の小さなテストを作成するかを選択できる場合、コード カバレッジの測定のみを行うということは、大規模なテストを作成する必要があることを意味します。

ただし、10 個の小さなテストのセットを作成すると、脆弱なテストがはるかに少なくなり、1 つの大きなテストよりもはるかに徹底的にアプリケーションをテストできます。したがって、コード カバレッジを測定することにより、特にテストの習慣が進化している組織では、間違ったインセンティブを設定することがよくあります。

于 2009-03-30T03:23:17.800 に答える
3

これがあなたの質問に対する直接的な回答ではないことはわかっていますが...

どんな種類のテストでも、それだけでは不十分です。単体テスト/コード カバレッジは開発者向けです。QA は、システム全体をテストする必要があります。ビジネス ユーザーは、システム全体をテストする必要があります。

逆に、QA はコードを完全にテストするので、開発者はテストすべきではありません。テストは補完的であり、異なるテストは異なるものを提供します。各テスト タイプは、別のテスト タイプが検出する可能性のあるものを見逃す可能性があります。

残りの開発と同じように、テストを近道にしないでください。バグを許してしまうだけです。

于 2009-03-30T02:43:43.963 に答える
2

コードカバレッジの最大の落とし穴の1つは、人々が話しているコードカバレッジのタイプを実際に指定せずに、コードカバレッジについて話しているだけであるということです。C0、C1、C2、およびさらに高いレベルのコードカバレッジの特性は大きく異なるため、「コードカバレッジ」について話すだけでは意味がありません。

たとえば、100%のフルパスカバレッジを達成することはほとんど不可能です。プログラムにn決定ポイントがある場合は、2 n個intのテストが必要です(定義によっては、値のすべてのビットが決定ポイントであるため、2秒を追加するだけの非常に単純な関数で100%のフルパスカバレッジを実現するには、 18446744073709551616テストが必要です)。ループが1つしかない場合は、すでに無限に多くのテストが必要です。

OTOH、100%のC0カバレッジを達成することは簡単です。

覚えておくべきもう1つの重要なことは、コードカバレッジはどのコードがテストされたかを教えてくれないということです。実行されたコードのみが表示されます。自分で試すことができます。100%のコードカバレッジを持つコードベースを使用してください。テストからすべてのアサーションを削除します。現在、コードベースは100%のカバレッジを維持していますが、テストするものは1つもありません。したがって、コードカバレッジは、何がテストされているかを示すのではなく、何がテストされていないかだけを示します。

于 2009-03-30T09:58:26.103 に答える
2

コードを変更して、さまざまな順列すべてでテストが失敗するかどうかを確認することにより、ブランチカバレッジを通じて分析を実行するツールがあります。

彼らのウェブサイトから直接:

Jumbleは、JUnitと連携して動作するクラスレベルのミューテーションテストツールです。ミューテーションテストの目的は、テストケースの有効性の尺度を提供することです。テストするコードに対して単一のミューテーションが実行され、対応するテストケースが実行されます。変更されたコードがテストに失敗した場合、これによりテストの信頼性が高まります。逆に、変更されたコードがテストに合格した場合、これはテストの欠陥を示します。

于 2009-04-01T01:10:50.863 に答える
2
  1. ターゲットを絞ったテストケースを作成する。
  2. コードの不十分な入力変動性テスト
  3. 多数の人工テストケースが実行されました。
  4. ノイズによる重要なテストの失敗に集中していません。
  5. ラインを実行するには、多くのコンポーネントの多くの条件が相互作用する必要があるため、欠陥の割り当てが困難です。

100%のカバレッジ目標を持つことの最悪の副作用は、テスト開発サイクルの多く(75%以上)をコーナーケースに当てることです。このようなポリシーのもう1つの悪い効果は、入力の範囲に対処するのではなく、コードの特定の行にヒットすることに集中することです。strcpy関数が少なくとも1回実行されてもかまいません。私はそれが多種多様な入力に対して実行されたことを本当に気にかけています。ポリシーを持つことは良いことです。しかし、非常に厳格な方針を持つことは悪いことです。コードカバレッジの100%メトリックは、コードが堅実であると見なされるために必要でも十分でもありません。

于 2009-03-30T02:20:27.280 に答える
1

コード カバレッジに問題はありません。私が間違っていると思うのは、100% の数字です。ある時点で収穫逓減の法則が働き、残りの 1% をテストする方が残りの 99% よりもコストがかかります。コード カバレッジは価値のある目標ですが、常識は大いに役に立ちます。

于 2009-03-30T02:22:22.003 に答える
1

!00% のコード カバレッジは、十分にテストされたコードが完全な神話であることを意味します。開発者として、私たちはシステムのハード/複雑/デリケートな部分を知っており、すべての行が少なくとも 1 回実行されたという意味のない数字よりも、これらの領域が適切にテストされ、50% のカバレッジしか得られないことを望んでいます。

実際の例で言えば、私が所属していた唯一の 100% カバレッジのチームは、私が今まで見た中で最悪のコードを書いていました。コード レビューの代わりに 100% のカバレッジが使用されました。テストに合格したにもかかわらず、ほとんどのコードが破棄されるという点で、結果は予想通りひどいものでした。

于 2009-03-30T02:42:17.587 に答える
1

単体テストからコード カバレッジを測定するための優れたツールがあります。そのため、コード カバレッジが 100% であることを信頼して、"テストが完了した" ことを示すのは魅力的です。本当じゃない。

他の人が言及しているように、コード カバレッジが 100% であっても、テストが適切に行われたとは言えません。また、コード カバレッジが 50% であっても、テストが適切に行われていないことを意味するわけではありません。

テストによって実行されるコード行数の測定は、1 つの指標にすぎません。また、適切な種類の関数入力をテストする必要があります。また、他の外部状態に応じて関数またはクラスがどのように動作するかもテストする必要があります。たとえば、一部のコードは、データベースまたはファイル内のデータに基づいて異なる機能を果たします。

最近、これについてブログを書いています: http://karwin.blogspot.com/2009/02/unit-test-coverage.html

于 2009-03-30T02:51:43.757 に答える
1

100% のコード カバレッジは、usnit テストが完了したことを意味するものではありません

function int divide(int a, int b) {
    return a/b;
}

たった 1 回の単体テストで、この関数の 100% のコード カバレッジが得られます。

return divide(4,2) == 2;

さて、この 100% カバレッジのユニット コードが、彼の機能が問題なく動作することを示していると主張する人は誰もいないでしょう。

コード カバレッジは、明らかなコード パスが欠落しているかどうかを知るための良い要素だと思いますが、慎重に使用します。

于 2009-03-30T03:52:17.997 に答える