Bazel によるコード カバレッジ

Bazel には、coverage サブコマンドがあり、bazel coverage でテストできるリポジトリのコード カバレッジ レポートを生成します。さまざまな言語エコシステムの特性により、特定のプロジェクトでこの機能を動作させるのは簡単ではありません。

このページでは、カバレッジ レポートの作成と表示の一般的なプロセスについて説明します。また、構成がよく知られている言語については、言語固有の注意事項も記載しています。まず 一般的なセクションを読み、次に 特定の言語の要件について読むことをおすすめします。リモート実行のセクションもご覧ください。このセクションでは、 追加の考慮事項について説明しています。

多くのカスタマイズが可能ですが、このドキュメントでは、 現在最もサポートされている lcov レポートの生成と使用に焦点を当てています。

カバレッジ レポートを作成する

準備

カバレッジ レポートを作成する基本的なワークフローには、次のものが必要です。

  • テスト ターゲットを含む基本的なリポジトリ
  • 言語固有のコード カバレッジ ツールがインストールされたツールチェーン
  • 正しい「インストルメンテーション」構成

最初の 2 つは言語固有で、ほとんどの場合簡単ですが、複雑なプロジェクトでは最後の 1 つが難しい場合があります。

この場合の「インストルメンテーション」とは、特定のターゲットに使用されるカバレッジ ツールを指します。Bazel では、ファイルの特定のサブセットに対してこの機能を有効にできます。このフラグは、インストルメンテーションを有効にしてテストされるターゲットのフィルタを指定します。--instrumentation_filterテストでインストルメンテーションを有効にするには、 --instrument_test_targets フラグが必要です。

デフォルトでは、bazel はターゲット パッケージの一致を試み、関連するフィルタを INFO メッセージとして出力します。

カバレッジを実行する

カバレッジ レポートを生成するには、bazel coverage --combined_report=lcov [target] を使用します。これにより、ターゲットのテストが実行され、ファイルごとに lcov 形式のカバレッジ レポートが生成されます。

完了すると、bazel は生成されたすべての カバレッジ ファイルを収集して 1 つにマージするアクションを実行します。このファイルは最終的に $(bazel info output_path)/_coverage/_coverage_report.dat に作成されます。

テストが失敗した場合もカバレッジ レポートが生成されますが、失敗したテストは対象外です。合格したテストのみがレポートされます。

カバレッジを表示する

カバレッジ レポートは、人が読めない lcov 形式でのみ出力されます。ここから、genhtml ユーティリティ(lcov プロジェクトの一部)を使用して、ウェブ ブラウザで表示できるレポートを生成できます。

genhtml --branch-coverage --output genhtml "$(bazel info output_path)/_coverage/_coverage_report.dat"

genhtml はソースコードも読み取り、これらのファイルで欠落しているカバレッジにアノテーションを付けます。この機能を動作させるには、bazel プロジェクトのルートで genhtml を実行する必要があります。

結果を表示するには、genhtml ディレクトリに生成された index.html ファイルを任意のウェブブラウザで開きます。

genhtml ツールまたは lcov カバレッジ形式の詳細については、lcov プロジェクトをご覧ください。

リモート実行

リモート テスト実行で実行する場合、いくつかの注意点があります。

  • レポート結合アクションはまだリモートで実行できません。これは、Bazel がカバレッジ出力ファイルをグラフの一部と見なさないため(Bazel の問題 #4685を参照)、結合アクションの入力として正しく処理できないためです。この問題を回避するには、--strategy=CoverageReport=local を使用します。
    • 注: Bazel が --strategy=CoverageReport=local,remote を試すように設定されている場合、Bazel が戦略を解決する方法により、 のように指定する必要がある場合があります。local,remote
  • 前述の結果として、--remote_download_minimal などのフラグも使用できません。
  • テストが以前にキャッシュされている場合、Bazel はカバレッジ情報を作成できません。この問題を回避するには、カバレッジ実行に --nocache_test_results を設定します。ただし、テスト時間が大幅に増加します。
  • --experimental_split_coverage_postprocessing--experimental_fetch_all_coverage_outputs
    • 通常、カバレッジはテスト アクションの一部として実行されるため、デフォルトでは、リモート実行の出力としてすべてのカバレッジが返されるわけではありません。これらのフラグはデフォルトをオーバーライドして、カバレッジ データを取得します。詳細については、Bazel の問題 #4685 をご覧ください 。

言語固有の構成

以降のセクションでは、Bazel でコード カバレッジを設定する際の言語固有の考慮事項について説明します。

C++

Linux

C++ カバレッジは、デフォルト構成でそのまま動作します。

macOS

GCOV_PREFIX_STRIP のデフォルト値はほぼ確実に正しくないため、手動で調整する必要があります。正しい値は設定によって異なります。

値が正しくない場合、カバレッジ データは見つかりません。

GCOV_PREFIX_STRIP=10 bazel coverage //foo:foo_test --test_env=GCOV_PREFIX_STRIP=10` を設定する例

Java

Java は、デフォルト構成でそのまま動作します。 bazel ツールチェーンには、JUnit を含む リモート実行に必要なものがすべて含まれています。

Python

Python でカバレッジ サポートを有効にするために必要な追加の手順については、rules_python カバレッジのドキュメント をご覧ください。