演習 - コード カバレッジのテストを実行する
単体テストに使用するツールと同様に、コード カバレッジで使用するツールは、プログラミング言語とアプリケーション フレームワークに応じて異なります。
Linux で実行する .NET アプリケーションをターゲットにする場合は、coverlet が一般的なオプションです。 coverlet は、.NET 用のクロス プラットフォームのコード カバレッジ ライブラリです。
.NET でのコード カバレッジの実行方法
コード カバレッジを収集する方法は、使用可能なコード カバレッジ ツールおよび使用するプログラミング言語とフレームワークによって異なります。
この Tailspin のシナリオでは、以下を確認します。
Windows 上の Visual Studio では、コード カバレッジを実行する方法が提供されます。
ただし、ここでは Linux でビルドを行うため、.NET 用のクロスプラットフォームのコード カバレッジ ライブラリである coverlet を使用できます。
単体テスト プロジェクトには、coverlet.msbuild という NuGet パッケージが必要です。
コード カバレッジの結果は、別のツールで処理できるように、XML ファイルに書き込まれます。 Azure Pipelines では Cobertura および JaCoCo カバレッジ結果の形式がサポートされます。
このモジュールでは、Cobertura を使用します。
Cobertura カバレッジの結果を人間が判読できる形式に変換するために、ReportGenerator というツールを使用できます。
ReportGenerator では、HTML を含む、多くの形式が提供されます。 HTML 形式では、.NET プロジェクトの各クラスの詳細なレポートが作成されます。
具体的には、Azure Pipelines と一致する視覚的な外観を提供する、HtmlInline_AzurePipelines という HTML 形式があります。
.NET ツールを管理する方法
ReportGenerator
などの .NET ツールは、コンソール アプリケーションを含む特殊な NuGet パッケージです。 .NET ツールは、グローバル ツールとして、またはローカル ツールとして管理できます。
グローバル ツールは一元的な場所にインストールされ、任意のディレクトリから呼び出すことができます。 1 つのバージョンのグローバル ツールが、マシン上のすべてのディレクトリに使用されます。
ローカル ツールは、特定のディレクトリにスコープが設定されている .NET ツールのより分離されたコピーです。 スコープを使用すると、異なるディレクトリに同じツールの別のバージョンを配置することができます。
特定のディレクトリのローカル ツールを管理するには、"マニフェスト ファイル" を使用します。 このファイルは JSON 形式であり、通常は dotnet-tools.json という名前です。 マニフェスト ファイルを使用すると、アプリケーションをビルドまたは実行するために必要な特定のツール バージョンを記述できます。
マニフェスト ファイルをソース管理とアプリケーションのソースに含めると、開発者とビルド システムは dotnet tool restore
コマンドを実行して、マニフェスト ファイルにリストされているすべてのツールをインストールできます。 新しいバージョンのローカル ツールが必要な場合は、マニフェスト ファイルのバージョンを更新するだけです。
より分離された状態を維持するために、このモジュールではローカル ツールを使用します。 ReportGenerator
ツールを含むツール マニフェストを作成します。 また、ビルド パイプラインを変更して、コード カバレッジの結果を人間が判読できる形式に変換する ReportGenerator
ツールをインストールします。
コード カバレッジをローカルで実行する
パイプライン コードを記述する前に、プロセスを確認するために手動で試すことができます。
Visual Studio Code で、統合ターミナルを開きます。
次の
dotnet new
コマンドを実行して、ローカル ツールのマニフェスト ファイルを作成します。dotnet new tool-manifest
このコマンドにより、.config/dotnet-tools.json という名前のファイルが作成されます。
次の
dotnet tool install
コマンドを実行して、ReportGenerator をインストールします。dotnet tool install dotnet-reportgenerator-globaltool
このコマンドでは、最新バージョンの
ReportGenerator
がインストールされ、ツール マニフェスト ファイルにエントリが追加されます。次の
dotnet add package
コマンドを実行して、coverlet.msbuild
パッケージを Tailspin.SpaceGame.Web.Tests プロジェクトに追加します。dotnet add Tailspin.SpaceGame.Web.Tests package coverlet.msbuild
次の
dotnet test
コマンドを実行して単体テストを行い、コード カバレッジを収集します。Note
Visual Studio で PowerShell ターミナルを使用している場合、行連結文字はバックティック (`) であるため、複数行のコマンドではその文字を円記号 (\) の代わりに使用します。
dotnet test --no-build \ --configuration Release \ /p:CollectCoverage=true \ /p:CoverletOutputFormat=cobertura \ /p:CoverletOutput=./TestResults/Coverage/
コマンドが失敗する場合は、次のように実行してみてください。
MSYS2_ARG_CONV_EXCL="*" dotnet test --no-build \ --configuration Release \ /p:CollectCoverage=true \ /p:CoverletOutputFormat=cobertura \ /p:CoverletOutput=./TestResults/Coverage/
このコマンドは、以前に実行したものと似ています。
/p:
フラグで、使用するコード カバレッジの形式と、結果を配置する場所を coverlet に示します。次の
dotnet tool run
コマンドを実行し、ReportGenerator
を使用して Cobertura ファイルを HTML に変換します。dotnet tool run reportgenerator \ -- -reports:./Tailspin.SpaceGame.Web.Tests/TestResults/Coverage/coverage.cobertura.xml \ -targetdir:./CodeCoverage \ -reporttypes:HtmlInline_AzurePipelines
プロジェクトのルートにある CodeCoverage フォルダーに多くの HTML ファイルが表示されます。
Visual Studio Code で、CodeCoverage フォルダーを展開して、index.htm を右クリックし、[エクスプローラーで表示する] を選択します (macOS の場合は [Reveal in Finder]、Linux の場合は [Open Containing Folder])。
エクスプローラー (macOS では Finder) で、index.htm をダブルクリックして Web ブラウザーで開きます。
カバレッジ レポートの概要が示されます。
ページの一番下までスクロールし、クラスの種類ごとにカバレッジの詳細を確認します。
TailSpin.SpaceGame.Web.LocalDocumentDBRepository<T>
へのリンクを選択して、さらに詳細を表示します。GetItemsAsync
メソッドは単体テストでカバーされていますが、CountItemsAsync
メソッドにはカバレッジがないことがわかります。FetchOnlyRequestedGameRegion
テスト メソッドではGetItemsAsync
メソッドが呼び出されますが、CountItemsAsync
メソッドは呼び出されないため、これは当然のことです。 (テスト コードを確認するには、DocumentDBRepository_GetItemsAsyncShould.cs ファイルを参照してください。)
分岐を作成する
これでコード カバレッジ レポートをローカルでビルドできるようになったため、同じタスクを実行するビルド パイプラインにタスクを追加できる準備ができました。
このセクションでは、作業を保持するために、unit-tests
ブランチに基づいて、code-coverage
という名前のブランチを作成します。 実際には、通常、このブランチは main
ブランチから作成します。
Visual Studio Code で、統合ターミナルを開きます。
ターミナルで、次の
git checkout
コマンドを実行して、code-coverage
という名前のブランチを作成します。git checkout -B code-coverage
ビルド タスクを追加する
このセクションでは、コード カバレッジを測定するタスクをビルド パイプラインに追加します。
Visual Studio Code で、azure-pipelines.yml を次のように変更します。
trigger: - '*' pool: vmImage: 'ubuntu-20.04' demands: - npm variables: buildConfiguration: 'Release' wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot' dotnetSdkVersion: '6.x' steps: - task: UseDotNet@2 displayName: 'Use .NET SDK $(dotnetSdkVersion)' inputs: version: '$(dotnetSdkVersion)' - task: Npm@1 displayName: 'Run npm install' inputs: verbose: false - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)' displayName: 'Compile Sass assets' - task: gulp@1 displayName: 'Run gulp tasks' - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt' displayName: 'Write build info' workingDirectory: $(wwwrootDir) - task: DotNetCoreCLI@2 displayName: 'Restore project dependencies' inputs: command: 'restore' projects: '**/*.csproj' - task: DotNetCoreCLI@2 displayName: 'Build the project - $(buildConfiguration)' inputs: command: 'build' arguments: '--no-restore --configuration $(buildConfiguration)' projects: '**/*.csproj' - task: DotNetCoreCLI@2 displayName: 'Install .NET tools from local manifest' inputs: command: custom custom: tool arguments: 'restore' - task: DotNetCoreCLI@2 displayName: 'Run unit tests - $(buildConfiguration)' inputs: command: 'test' arguments: '--no-build --configuration $(buildConfiguration) /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput=$(Build.SourcesDirectory)/TestResults/Coverage/' publishTestResults: true projects: '**/*.Tests.csproj' - task: DotNetCoreCLI@2 displayName: 'Create code coverage report' inputs: command: custom custom: tool arguments: 'run reportgenerator -reports:$(Build.SourcesDirectory)/**/coverage.cobertura.xml -targetdir:$(Build.SourcesDirectory)/CodeCoverage -reporttypes:HtmlInline_AzurePipelines' - task: PublishCodeCoverageResults@1 displayName: 'Publish code coverage report' inputs: codeCoverageTool: 'cobertura' summaryFileLocation: '$(Build.SourcesDirectory)/**/coverage.cobertura.xml' - task: DotNetCoreCLI@2 displayName: 'Publish the project - $(buildConfiguration)' inputs: command: 'publish' projects: '**/*.csproj' publishWebProjects: false arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)' zipAfterPublish: true - task: PublishBuildArtifacts@1 displayName: 'Publish Artifact: drop' condition: succeeded()
このバージョンは既存の構成に基づきます。 追加した部分の概要を次に示します。
Azure Pipelines タスク Display name 説明 DotNetCoreCLI@2
.NET ツールをローカル マニフェストからインストールする マニフェスト ファイル (dotnet-tools.json) にリストされているツールをインストールします DotNetCoreCLI@2
Run unit tests - $(buildConfiguration) 単体テストを実行し、Cobertura 形式でのコード カバレッジの収集も行います DotNetCoreCLI@2
Create code coverage report Cobertura の出力を HTML に変換します PublishCodeCoverageResults@1
Publish code coverage report パイプラインにレポートを発行します
変更をコミットしてブランチを GitHub にプッシュする
ここでは、変更を GitHub にプッシュし、パイプラインの実行を確認します。 現在、code-coverage
ブランチにいることを思い出してください。
必須ではありませんが、ここで各ファイルを個別に追加してコミットし、それぞれの変更がわかりやすいコミット メッセージに関連付けられるようにします。
Visual Studio Code で、ターミナルに移動します。
coverlet.msbuild
パッケージへの参照が含まれるようになった、Tailspin.SpaceGame.Web.Tests.csproj ファイルを追加してコミットします。git add Tailspin.SpaceGame.Web.Tests/Tailspin.SpaceGame.Web.Tests.csproj git commit -m "Add coverlet.msbuild package"
ツール マニフェスト ファイル (dotnet-tools.json) を追加してコミットします。
git add .config/dotnet-tools.json git commit -m "Add code coverage"
更新されたビルド構成を含む azure-pipelines.yml を追加してコミットします。
git add azure-pipelines.yml git commit -m "Add code coverage"
code-coverage
ブランチを GitHub にプッシュします。git push origin code-coverage
Azure Pipelines でのテストの実行を監視する
ここで、パイプラインでのテストの実行を確認してから、Azure Test Plans からの結果を視覚化します。
Azure Pipelines で、手順ごとにビルドをトレースします。
ビルドが完了したら、概要ページに戻り、[コード カバレッジ] タブを選びます。
ローカルでテストを実行したときと同じ結果が表示されます。
オプションの手順として、Azure Pipelines からの結果を調べることができます。
ダッシュボード ウィジェットを追加する
前のセクションでは、[テスト結果の傾向] ウィジェットをダッシュボードに追加しました。これを使って、他のユーザーがテスト結果の傾向を時間の経過に従ってすばやく確認できます。
ここでは、コード カバレッジの概要を示す 2 番目のウィジェットを追加します。
新しいブラウザー タブで、marketplace.visualstudio.com に移動します。
[Azure DevOps] タブで、「code coverage」を検索します。
[Code Coverage Widgets] を選択します (Shane Davis によって公開されています)。
[Get it free](無料で入手) を選択します。
ドロップダウン リストで、対象の Azure DevOps 組織を選択します。
[インストール] を選択します。
Azure DevOps に戻ります。
[Overview]>[Dashboards] に移動します。
[編集] を選択します。
「Code Coverage」を検索し、[Code Coverage] を選択します。
コード カバレッジをキャンバスにドラッグします。
歯車アイコンを選択してウィジェットを構成します。
次の設定を除き、すべての設定を既定のままにします。
- 幅:「2」と入力します
- ビルド定義:パイプラインを選択します
- Coverage measurement (カバレッジの測定): [行数] を選択します
[保存] を選択します。
[編集完了] を選択します。
ウィジェットには、単体テストでカバーされるコードの割合が表示されます。
これで、パイプラインにコード カバレッジが設定されました。 既存のコード カバレッジは低くなっていますが、時間の経過と共に改善できるベースラインがあります。
後から、テストでカバレッジの最小しきい値が提供されるかどうかを確認するように、coverlet を構成できます。 しきい値は、要件に応じて 30%、50%、または 80% のカバレッジにすることができます。 テストでこれより少ない量がカバーされている場合、ビルドは失敗します。
コード カバレッジ ファイルを削除する
先ほど Reportgenerator
を実行したときに、プロジェクトのルートにある CodeCoverage フォルダーに多くの HTML ファイルが表示されていたことを思い出してください。
これらの HTML ファイルは、ソース管理に含めることは意図されておらず、必要なくなりました。 プロジェクトの .gitignore ファイルは、CodeCoverage ディレクトリの内容を無視するように既に設定されていますが、今後のモジュールで Git リポジトリに追加されないように、これらのファイルを削除することをお勧めします。
Visual Studio Code で、ターミナル ウィンドウに移動し、プロジェクトのルート ディレクトリでこのコマンドを実行します。
rm -rf CodeCoverage/