Code Coverage の設定

This product is not supported for your selected Datadog site. ().

Code Coverage の設定には、以下の手順が含まれます。

  1. Datadog UI で ソースコードプロバイダーとの統合を構成します。
  2. Datadog でコードカバレッジのデータアクセス権限を構成します。
  3. 必要に応じて、カバレッジのしきい値に基づいてプルリクエストをブロックする PR Gate を構成します。
  4. CI パイプラインを更新して、コードカバレッジレポートを Datadog にアップロードします。

ソースコードプロバイダーとの統合

Code Coverage は以下をサポートしています。

GitHub リポジトリを Datadog に接続する方法については、GitHub 統合ドキュメントの手順に従ってください。

Code Coverage には、以下の GitHub App 権限が必要です。

権限アクセスレベル目的
コンテンツ読み取り詳細なカバレッジ UI にソースコードを表示します。
プルリクエスト書き込みカバレッジ UI に PR データを表示し、PR コメントを書き込みます。
チェック書き込みカバレッジ PR ゲートを作成します。

以下の Webhook が必要です。

Webhook目的
プルリクエストPR データの更新を受信します。
プルリクエストレビューPR データの更新を受信します。
プルリクエストレビューコメントPR データの更新を受信します。
プッシュGit コミットメタデータを受信します。

すべてが正しく構成されている場合、Datadog のGitHub 統合ページに緑色のチェックマークが表示されます。

GitHub App 統合の成功チェック
Datadog 管理の Marketplace App またはデフォルト設定のカスタムアプリを使用している場合、必要な権限と Webhook が含まれています。

GitLab リポジトリを Datadog に接続する方法については、GitLab ソースコード統合ドキュメントの手順に従ってください。

詳細については、Datadog ソースコード統合ガイドを参照してください。

Datadog ソースコード統合ガイドの手順に従って、Azure DevOps リポジトリを Datadog に接続します。 Azure DevOps ソースコード統合を使用します。

ソースコードプロバイダーから収集されるデータの詳細については、収集されるデータを参照してください。

データアクセス権限

Datadog 管理ロールではなくカスタムロールを使用している場合は、コードカバレッジデータを表示する必要があるロールに対して、Code Coverage Read 権限を必ず有効にしてください。

ロール設定に移動し、必要なロールの Edit をクリックして、そのロールに Code Coverage Read 権限を追加し、変更を保存します。

より詳細な制御を行うには、Data Access Control を使用して、組織全体ではなくリポジトリごとにコードカバレッジデータを制限します。これにより、ソースパスやテスト名など、カバレッジレポート内の機密情報がチームの境界を越えることを防ぎます。

Datadog で、Organization Settings > Data Access Control に移動し、Software Delivery と制限したいリポジトリをスコープとする制限付きデータセットを作成します。それを表示する必要があるロールまたはチームにアクセス権を付与します。

PR ゲート

PR カバレッジでゲートを設定したい場合は、次の 2 つの方法のいずれかで PR ゲートのルールを設定できます。

  • Datadog UI: PR ゲートのルール作成に移動し、合計カバレッジまたはパッチカバレッジでゲートを設定するルールを構成します。
  • YAML 構成ファイル: code-coverage.datadog.yml ファイルでゲートを定義します。これにより、リポジトリと一緒にコードとしてゲートを管理できます。

プルリクエストが開かれたとき、または更新されたときに、両方のソースのルールが評価されます。YAML ゲートの構文と例については、構成を参照してください。

コードカバレッジレポートをアップロードする

サポートされている Test Optimization ライブラリを使用して自動的に、または CI 環境で datadog-ci CLI を実行して手動で、コードカバレッジレポートファイルを Datadog にアップロードします。

コードカバレッジレポートのアップロード中に収集されるデータの詳細については、収集されるデータを参照してください。

Test Optimization でレポートを自動的にアップロードする

サポートされているライブラリとバージョン

自動コードカバレッジレポートのアップロードは、以下の Test Optimization ライブラリのバージョンでサポートされています。

ライブラリ最初にサポートされるバージョンカバレッジソース
Ruby datadog-ci1.27.0SimpleCov
JavaScript dd-trace 5.x5.85.0Jest、Vitest、または NYC カバレッジ
JavaScript dd-trace 6.x6.0.0Jest、Vitest、または NYC カバレッジ
Python ddtrace4.4.0coverage.py
Java dd-java-agent1.53.0JaCoCo

これらのバージョン要件は、Test Optimization ライブラリによる自動アップロードにのみ適用されます。

自動アップロードを有効にする

Code Coverage 設定は、組織、リポジトリ、またはテストサービスのレベルで適用できます。

  1. ライブラリの Test Optimization のセットアップを完了してください。

  2. サポートされているバージョンのライブラリにアップグレードしてください。

  3. Code Coverage で CI/CD Optimization settings をオンにしてください。

    組織レベルの CI/CD Optimization 設定にある Code Coverage のトグル。
  4. サポートされているライブラリとバージョンに記載されているソースからカバレッジレポートを生成するテストコマンドを実行してください。

コマンドが終了すると、ライブラリがレポートを Datadog にアップロードします。

ライブラリによってアップロードされたレポートを整理およびフィルタリングするには、自動アップロードされたレポートへのフラグの追加を参照してください。このページには、DD_CODE_COVERAGE_FLAGS をサポートするライブラリとバージョンが記載されています。

サポートされているカバレッジレポート形式

Datadog は以下のカバレッジデータ形式をサポートしています。展開して例を確認してください。

TN:
SF:src/example.c
FN:3,add
FNDA:5,add
FNF:1
FNH:1
DA:3,5
DA:4,5
DA:5,5
DA:8,0
DA:9,0
LF:5
LH:3
BRDA:4,0,0,5
BRDA:4,0,1,0
BRF:2
BRH:1
end_of_record
mode: atomic
example/calculator.go:51.148,53.2 1 0
example/calculator.go:55.190,61.15 3 0
example/calculator.go:61.15,64.3 2 0
example/calculator.go:66.2,67.16 2 0
example/calculator.go:67.16,69.3 1 0
example/clients/api_client.go:27.87,31.2 3 2
example/clients/api_client.go:34.85,36.2 1 3
example/clients/api_client.go:39.126,44.2 4 3
example/clients/api_client.go:47.106,50.2 2 3
example/notifications/notifier.go:49.79,51.2 1 3
example/notifications/notifier.go:60.33,69.2 1 0
example/notifications/notifier.go:79.131,86.15 3 2
example/notifications/notifier.go:104.3,104.10 1 3
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE coverage SYSTEM "http://cobertura.sourceforge.net/xml/coverage-04.dtd">
<coverage lines-valid="5" lines-covered="3" line-rate="0.6" branches-valid="2" branches-covered="1" branch-rate="0.5" timestamp="1690658886" version="1.9">
  <sources>
    <source>src</source>
  </sources>
  <packages>
    <package name="example" line-rate="0.6" branch-rate="0.5">
      <classes>
        <class name="Example" filename="example/Example.java" line-rate="0.6" branch-rate="0.5">
          <methods>
            <method name="add" signature="(II)I" line-rate="1.0" branch-rate="1.0">
              <lines>
                <line number="3" hits="5"/>
                <line number="4" hits="5" branch="true" condition-coverage="50% (1/2)"/>
                <line number="5" hits="5"/>
              </lines>
            </method>
          </methods>
          <lines>
            <line number="3" hits="5"/>
            <line number="4" hits="5" branch="true" condition-coverage="50% (1/2)"/>
            <line number="5" hits="5"/>
            <line number="8" hits="0"/>
            <line number="9" hits="0"/>
          </lines>
        </class>
      </classes>
    </package>
  </packages>
</coverage>
<?xml version="1.0" encoding="UTF-8"?>
<report name="Example">
  <sessioninfo id="SessionId" start="1690658886000" dump="1690658887000"/>
  <package name="example">
    <sourcefile name="Example.java">
      <line nr="3" mi="0" ci="5"/>
      <line nr="4" mi="0" ci="5" mb="1" cb="1"/>
      <line nr="5" mi="0" ci="5"/>
      <line nr="8" mi="1" ci="0"/>
      <line nr="9" mi="1" ci="0"/>
    </sourcefile>
  </package>
</report>
<coverage generated="1661852015">
    <project timestamp="1661852015">
        <file name="/var/www/html/src/App/Console/CronjobRunnerCommand.php">
            <class name="App\Console\CronjobRunnerCommand" namespace="global">
                <metrics complexity="3" methods="3" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="4" coveredstatements="0" elements="7" coveredelements="0"/>
            </class>
            <line num="18" type="method" name="__construct" visibility="public" complexity="1" crap="2" count="0"/>
            <line num="20" type="stmt" count="1"/>
            <line num="27" type="stmt" count="0"/>
            <line num="30" type="method" name="execute" visibility="protected" complexity="1" crap="2" count="0"/>
            <line num="32" type="stmt" count="0"/>
            <metrics loc="35" ncloc="35" classes="1" methods="3" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="4" coveredstatements="0" elements="7" coveredelements="0"/>
        </file>
        <file name="/var/www/html/src/App/Console/CronjobRunnerCommand2.php">
            <line num="42" type="stmt" count="1"/>
        </file>
    </project>
</coverage>
<?xml version="1.0" encoding="utf-8"?>
<CoverageSession xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Modules>
    <Module hash="ABC123">
      <ModulePath>Example.dll</ModulePath>
      <Files>
        <File uid="1" fullPath="src\example\Example.cs" />
      </Files>
      <Classes>
        <Class>
          <Methods>
            <Method visited="true" cyclomaticComplexity="1" sequenceCoverage="100">
              <FileRef uid="1"/>
              <SequencePoints>
                <SequencePoint vc="5" sl="3" />
                <SequencePoint vc="5" sl="4" />
                <SequencePoint vc="5" sl="5" />
                <SequencePoint vc="0" sl="9" />
              </SequencePoints>
              <BranchPoints>
                <BranchPoint vc="5" sl="4" path="0"/>
                <BranchPoint vc="0" sl="4" path="1"/>
              </BranchPoints>
            </Method>
          </Methods>
        </Class>
      </Classes>
    </Module>
  </Modules>
</CoverageSession>
{
  "meta": {
    "simplecov_version": "0.21.2"
  },
  "coverage": {
    "/path/to/file1.rb": {
      "lines": [
        null,
        1,
        2,
        0,
        null,
        1,
        null,
        null,
        null,
        "ignored",
        "ignored",
        "ignored",
        null
      ],
      "branches": []
    },
    "/path/to/file2.rb": {
      "lines": [1, 1, null, 0, 1],
      "branches": []
    }
  }
}

datadog-ci CLI をインストールしてください

GitHub Actions を使用している場合は、このインストール手順をスキップできます。以下の GitHub Actions アップロード方法では、専用のアクションを使用して datadog-ci のインストールを自動的に行います。

スタンドアロンバイナリは、Datadog CI リリースで提供されています。linux-x64、linux-arm64、darwin-x64、darwin-arm64 (macOS)、および win-x64 (Windows) のアーキテクチャがサポートされています。インストールするには、ターミナルから以下を実行します。

curl -L --fail "https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_linux-x64" --output "/usr/local/bin/datadog-ci" && chmod +x /usr/local/bin/datadog-ci

次に、datadog-ci を使用して任意のコマンドを実行します。

datadog-ci version
curl -L --fail "https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_darwin-x64" --output "/usr/local/bin/datadog-ci" && chmod +x /usr/local/bin/datadog-ci

次に、datadog-ci を使用して任意のコマンドを実行します。

datadog-ci version
Invoke-WebRequest -Uri "https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_win-x64" -OutFile "datadog-ci.exe"

次に、Start-Process -FilePath "datadog-ci.exe" を使用して任意のコマンドを実行します。

Start-Process -FilePath "./datadog-ci.exe" -ArgumentList version

npm

または、CI 環境で Node.js が利用可能な場合は、npm を使用して datadog-ci CLI をグローバルにインストールします。

npm install -g @datadog/datadog-ci

Docker イメージ

または、Datadog CI Docker イメージに基づくコンテナで実行するように CI ジョブを更新することもできます。 このイメージには datadog-ci がプリインストールされており、すぐに使用できます。

カバレッジレポートのアップロード

Datadog は、同じコミットに対するすべてのレポートをバックエンドで自動的に集約します。アップロード前にカバレッジレポートをマージする必要はありません。

コードカバレッジレポートを Datadog にアップロードするには、次のコマンドを実行します。有効な Datadog API キー (DD_API_KEY) と、カバレッジレポートファイル自体またはそれらを含むディレクトリへの 1 つ以上のファイルパスを指定します。

Datadog Code Coverage Upload GitHub Action を使用します。このアクションは datadog-ci を自動的にインストールして実行するため、追加のセットアップは不要です。


steps:
- name: Upload coverage reports to Datadog
  uses: DataDog/coverage-upload-github-action@v1
  with:
    api_key: ${{ secrets.DD_API_KEY }}
    site: 

または、datadog-ci がインストールされている場合は、直接実行することもできます。


steps:
- name: Upload coverage reports to Datadog
  run: datadog-ci coverage upload .
  env:
    DD_API_KEY: ${{ secrets.DD_API_KEY }}
    DD_SITE: 


test:
  stage: test
  script:
    - ... # run your tests and generate coverage reports
    - datadog-ci coverage upload . # make sure to add the DD_API_KEY CI/CD variable

- script: datadog-ci coverage upload --format=clover coverage/clover.xml displayName: 'Upload coverage to Datadog' env: DD_API_KEY: $(DD_API_KEY) DD_SITE: 'datadoghq.com'

このコマンドは、指定されたディレクトリを再帰的に検索してサポートされているカバレッジレポートファイルを探すため、通常は現在のディレクトリ (.) を指定するだけで十分です。 datadog-ci ドキュメントで datadog-ci coverage upload コマンドの詳細を参照してください。

コードカバレッジレポートのアップロードが完了するとすぐに、Datadog はコードカバレッジのパーセンテージ値を含む PR コメントを追加します。コメントにファイルごとの合計カバレッジとパッチカバレッジの内訳を追加するには、PR コメントを参照してください。 また、Datadog の Code Coverage ページでは、プルリクエストごとに集計されたカバレッジデータを表示でき、個々のファイルやコード行を調査することもできます。

トラブルシューティング

カバレッジアップロードコマンドがカバレッジレポートファイルを検出しない

datadog-ci coverage upload コマンドは、ファイル名や拡張子などのヒューリスティックを使用して、指定されたディレクトリ内のサポートされているカバレッジレポートファイルを自動的に検出します。 カバレッジレポートファイルが想定されるパターンと一致しない場合、コマンドがそれらを自動的に検出できないことがあります。その場合は、レポート形式を指定し、ファイルパスを位置引数として指定してください。たとえば、次のようにします。

datadog-ci coverage upload --format=lcov \
  src/coverage-reports/unit-tests/coverage.info \
  src/coverage-reports/e2e-tests/coverage.info

カバレッジアップロードが「Format could not be detected」エラーで失敗する

datadog-ci coverage upload コマンドは、カバレッジレポートファイルの内容とファイル拡張子に基づいて、その形式を自動的に検出します。 コマンドが以下のエラーで失敗する場合、

Invalid coverage report file [...]: format could not be detected

以下のように、--format オプションを使用して形式を明示的に指定してください。

datadog-ci coverage upload --format=cobertura reports/cobertura.xml

カバレッジアップロードで「Could not sync git metadata」エラーが出力される

Git メタデータのアップロードは、CI プロバイダーを Datadog と直接統合できない場合にのみ必要です。 Datadog GitHub アプリや GitLab 統合などのソースコードプロバイダー統合を使用している場合は、以下のように --skip-git-metadata-upload=1 フラグを datadog-ci coverage upload コマンドに渡すことで、Git メタデータのアップロードを無効にできます。

datadog-ci coverage upload --skip-git-metadata-upload=1 .

Datadog UI の PR ビューに変更されたファイルが表示されない

デフォルトでは、「Changed files」テーブルには、アップロードされたカバレッジレポートに存在する実行可能なソースコードファイルのみが含まれます。 テーブルヘッダーで Non-executable files または All を選択すると、実行可能かどうかにかかわらず、PR で変更されたすべてのファイルが表示されます。

ソースコードファイルが誤って実行不可としてマークされている場合、アップロードされたカバレッジレポートから漏れている可能性があります。 関連するすべてのレポートをアップロードしていることを確認し、カバレッジツールの設定を再確認して、該当するすべてのファイルに対してカバレッジデータが収集されていることを確認してください。

テストソースは、カバレッジを測定する本番コードベースの一部ではないため、実行可能なファイルとはみなされません。

Datadog UI に誤ったファイルパスが表示される

Code Coverage は、カバレッジレポート内のファイルパスが、絶対パスまたはリポジトリルートからの相対パスであることを前提としています。 レポート内のパスがリポジトリ内の別のディレクトリからの相対パスである場合は、datadog-ci coverage upload コマンドを実行する際に --base-path オプションを使用して、正しいベースパス (リポジトリルートからの相対パス) を次のように指定してください。

datadog-ci coverage upload --base-path=frontend/src .

実行不可能な行による不正確なカバレッジ

一部のカバレッジツールは、実行不可能な行 (コメント、空白行、閉じ括弧など) をレポートに含め、それらを未カバレッジとしてカウントします。これにより、カバレッジ率が低下し、決して実行されない行に対して誤ったネガティブ (偽陰性) が発生する可能性があります。

アップロード中、CLI はソースファイルを自動的にスキャンしてこれらの実行不可能な行を特定し、カバレッジ計算から除外できるようにします。

ファイル修正は、Go、Kotlin、C/C++、Swift、Objective-C、および PHP の各言語をサポートしています。

この動作は、以下のオプションで制御できます。

  • --disable-file-fixes: ファイル修正の生成を完全に無効にします。
  • --file-fixes-search-path <dir>: ソースファイルのスキャンに使用するルートディレクトリを上書きします。デフォルトでは、リポジトリのルートが使用されます。これはモノレポの場合や、カバレッジレポートがコードベースのサブセットのみを対象としている場合に便利です。スキャン対象のディレクトリツリーが制限されるため、スキャンが高速化されます。

Datadog UI とカバレッジレポートの値の不一致

Datadog は、同じコミットに対するカバレッジレポートを自動的にマージします。 その結果、Datadog UI に表示されるカバレッジ率が、個々のカバレッジレポートの値と異なる場合があります。特に、それらのレポートに重複するソースコードファイルのエントリが含まれている場合に発生します。

Datadog にアップロードする前に外部ツール (ReportGeneratorなど) を使用してカバレッジレポートをマージする場合は、 マージされたレポートにソースコードファイルの重複エントリが含まれないようにしてください。 Datadog はレポート間で重複するファイルを排除 (デデュプリケート) します。これにより、元のカバレッジ値と Datadog UI に表示されるマージ後の値との間に差異が生じる可能性があります。

レポートがどのようにマージされ、各行のステータスがどのようにカウントされるかの詳細については、Code Coverage Calculation を参照してください。

参考資料