web-dev-qa-db-ja.com

ヒットできないC ++コードの行を無視するようにgcovに指示するにはどうすればよいですか?

私はgcovを使用してC++コードのカバレッジを測定しています。 100%のカバレッジを取得したいのですが、理論的にはヒットできないコード行がいくつかあるという事実によって妨げられています(実装する必要があるが呼び出されることのないメソッド、switchステートメントなど)。これらの各ブランチにはassert( false );ステートメントが含まれていますが、gcovはそれらをヒットしていないものとしてマークします。

これらのブランチを無視するようにgcovに指示できるようにしたいと思います。 gcovにその情報を提供する方法はありますか?ソースコードに注釈を付けるか、他のメカニズムによってですか?

47
jchl

Lcovを使用してください。それはgcovの複雑さを隠し、素晴らしい出力を生成し、テストごとに詳細な出力を可能にし、簡単なファイルフィルタリングと-ta-taa-すでにレビューされた行の行マーカーを備えています:

Geninfo(1)から:

次のマーカーはgeninfoによって認識されます。

  • LCOV_EXCL_LINE
    • このマーカーを含む行は除外されます。
  • LCOV_EXCL_START
    • 除外されたセクションの開始をマークします。現在の行はこのセクションの一部です。
  • LCOV_EXCL_STOP
    • 除外されたセクションの終わりを示します。現在の行はこのセクションの一部ではありません。
34
Torsten Scheck

gcovr というツールを使用してgcovの出力を要約でき、( 少なくともバージョン3.4から )lcovと同じ除外マーカーをサポートします。

から この答え

次のマーカーはgeninfoによって認識されます。

  • LCOV_EXCL_LINE
    • このマーカーを含む行は除外されます。
  • LCOV_EXCL_START
    • 除外されたセクションの開始をマークします。現在の行はこのセクションの一部です。
  • LCOV_EXCL_STOP
    • 除外されたセクションの終わりを示します。現在の行はこのセクションの一部ではありません。

上記の'LCOV''GCOV'または'GCOVR'に置き換えることもできます。それらはすべて機能します。

4
Simon Pickup

理論的にヒットできないコードパスを直接攻撃することによってgcovをシャットダウンするためだけに存在する、関連する関数の単体テストを紹介できますか?それらはユニットテストであるため、状況の「不可能性」を無視する可能性があります。呼び出されることのない関数を呼び出したり、無効な列挙値を渡してデフォルトのブランチをキャッチしたりする可能性があります。

次に、NDEBUGでコンパイルされたコードのバージョンでのみこれらのテストを実行するか、テストフレームワークがサポートするものは何でも、アサートがトリガーされることをテストするハーネスでテストを実行します。

コードの機能要件を含む仕様ではなく、コードがそこにある必要があると仕様が言っているのは少し奇妙だと思います。特に、テストがこれらの要件をテストしていないことを意味します。これは、要件を機能的に保つための理由と同じです。個人的には、「無効な列挙値で呼び出された場合、関数はassertに失敗します。呼び出し元は、リリースモードで無効な列挙値で関数を呼び出さないでください」と仕様を変更したいと思います。またはそのようなもの。

おそらく現在それが言っていることは、「すべてのswitchステートメントはデフォルトのケースを持たなければならない」という線に沿っています。しかし、それは、コーディング標準がデッドコードを導入することによって観察可能な動作(少なくともgcovで観察可能)を妨害していることを意味します。コーディング標準はそれを行うべきではないので、機能仕様は可能であればコーディング標準を考慮に入れるべきです。

それができない場合は、ヒットできないコードを#if !GCOV_BUILDでラップし、gcovの利益のために別のビルドを実行することができます。このビルドはいくつかの要件に失敗しますが、コードの分析が正しいことを条件として、テストスイートが他のすべてをテストすることを確信できます。

編集:あなたは危険なコードジェネレーターを使用していると言いますが、ソースコードに注釈を付けることによって解決策も求めています。ソースを変更する場合、多くの場合、デッドコードを削除できますか?生成されたソースを変更することが理想的ではありませんが、ニーズは...

1
Steve Jessop

私はこれが可能だとは思わない。 Gcovはgccに依存して、カバレッジ出力を生成するための追加のコードを生成します。 GCov自体はデータを解析するだけです。これは、Gcovがgccよりも優れたコードを分析できないことを意味します(そして、-Wallを使用し、到達不能として報告されたコードを削除したと思います)。

再配置可能関数はどこからでも呼び出すことができ、外部dllや実行可能ファイルでさえも呼び出すことができるため、コンパイラが呼び出されない再配置可能関数やこれらの関数の入力を知る方法はありません。

必要な情報を取得するには、おそらくいくつかの偽の静的分析ツールを使用する必要があります。

0
doron