多くの言語には、コードカバレッジを測定するさまざまなツールがあります。 しかし、これはどの程度正確に機能しますか?
私はいくつかのアイデアを持っています、これがどのように機能するか:
カバレッジツールは、デバッガーでコードを実行してステップスルーするだけですか?ある種の静的分析が使用されていますか?または、一部のツールは、コードが実行されたときに呼び出されるマーカーをソースコードに挿入するだけですか?また、プラットフォームが、より低いレベルでカバレッジを測定するためのツールを提供する場合もあると思います。
コードカバレッジツールは、次の2つのフレーバーで機能します。
カバレッジ測定は、どのコードが実行であるかを測定するため、動的品質保証ツールです。静的分析では不十分です。
デバッガーが使用可能な場合、これにより、各ステートメントの後で通常の実行を簡単に中断し、そのステートメントを対象として記録することが容易になります。ただし、これらすべての中断には顕著な実行時コストがかかり、テストの速度が低下します。デバッガベースのカバレッジツールは、多くの場合、収集できるカバレッジの種類のデバッグインターフェイスによって制限されます。例えば。 bar() && baz()
のような式内でブランチカバレッジを収集できない場合があります。
インストルメンテーションは、コンパイラーまたはコンパイル後のステップによって実行され、カバレッジを記録する実行可能ファイルにコードを挿入します。ソースコードは変更されません。これは、デバッガベースのソリューションよりも実行時のオーバーヘッドが少なくなりますが、特別なカバレッジ収集モードでプログラムをコンパイルする必要があります。
例として、Python coverage.py
ツールはPythonの組み込みトレースフックを使用します。対照的に、GCCとClangは、-fprofile-arcs -ftest-coverage
でコンパイルするときにインストルメンテーションベースのカバレッジコレクションをサポートします。フラグ(最適化を無効にし、デバッグビルドを使用する必要があります:-g -O0
)ブランチカバレッジを収集する場合の利点:コンパイラは、ソースコードで簡単に表示できるブランチだけでなく、マシンコードに存在するすべてのブランチを認識します。 。プログラムが実行されると、gcov、lcov、gcovrなどのツールを使用してレポートにマッサージできるファイルにカバレッジが記録されます(開示:私はgcovrを維持しています)。
一般に、カバレッジ測定にはプロファイラーと同じ種類のデータが必要です。多くの場合、これらのツールはまったく同じインフラストラクチャを使用します。ただし、ホットスポットは頻繁に実行されるため、プロファイラーは精度を下げる余裕があります。カバレッジツールとは異なり、samplingを使用して、どのコードが実行されるかを測定できます。サンプリングプロファイラーは定期的にプロセスを中断し、現在の場所を指すスタックトレースを収集します。これは、各ステートメントで発生する頻度は少なく、多くの場合、数ミリ秒ごとに発生します。したがって、パフォーマンスへの影響は少なくなりますが、データの精度は低くなります。
場合によります。
コンパイルされた言語の場合、通常はコンパイラサポートを使用します。つまり、コンパイラは1行あたりのカウンタを増やす追加の命令を追加します。 (むしろ、ブランチレスブロックごとに。)
ジャストインタイムコンパイルされた言語の場合も同じことが当てはまりますが、ほとんどの場合、追加の命令を挿入するのはJITコンパイラです。
解釈された環境では、インタープリターはプロファイラーが情報を取得するためのインターフェースを提供する場合があります。