Publishing Code Coverage in Your Azure DevOps Build Pipeline

Last week we used Coverlet and ReportGenerator to collect code coverage on our development machines. In this post we continue this journey and extend our build pipelines to get a nice coverage report with every continuous integration build.


Extending the test task

We can collect the code coverage files in the build pipeline by amending the call to dotnet test with the --collect:"XPlat Code Coverage" option:

If we run our pipeline, it should create coverage.cobertura.xml files.

Depending on whether you have enabled the option “Publish test results and code coverage“, you will find the generated files either in the temporary folder of the build agent or inside your test projects.


Common mistake: missing data collector

If there are no code coverage files, check the log of the test task. You may find warnings like this one all over the place:

Unable to find a datacollector with friendly name ‘XPlat Code Coverage’.

This annoying warning happens when you specify *.dll files instead of the *.sln or the *.csproj files as part of the test task. Change it to *.csproj and it will find the datacollector.

This error is especially nasty to track down because dotnet test works with *.dll without any problems. Only after you add the code coverage option the file type starts to matter.


Install the ReportGenerator task

While you can install ReportGenerator as a global tool on your build server, I suggest you install it as a task for your pipeline. You can find this extension in the Visual Studio Market Place.

After installing it for your Azure DevOps organisation, you need to hit the refresh button in the pipeline before you can select this new task.


Configure the ReportGenerator task

The most important configuration for ReportGenerator is the location of the Reports. Set the Report property to these two folders:

(The first tests folder must match the folder in which you put your test projects).

If you specify both locations, it does not matter if you enabled the publishing of the test results or not.

For the Report types we best use these two options:

This creates a HTML report that you can explore directly in Azure DevOps and the combined Cobertura file makes sure that you get the numerical value for your code coverage as part of the build summary.

Put the settings in their matching fields


Publish the coverage data

We need to add the task “Publish code coverage results” to our pipeline to get the code coverage results as part of our builds. Unfortunately, version 2 of this task only works if you have by chance the exact version of .Net 2.x that it depends on. For everyone else, switch to version 1 of this task and it will work independently of .Net 2.

The Summary file must point to the coveragereport/cobertura.xml file.

The Report directory points to coveragereport (which contains the HTML report).


Prevent the default coverage report

The last and probably strangest hoop you need to jump for code coverage in Azure DevOps is to disable the default coverage report. This report will have the strangest values and may be 2 hours in the future or 6 years in the past.

We can prevent the default report by adding this variable to our build pipeline:


The result

If you now save your build pipeline and run it, it should create a code coverage report and show you the percentage of covered lines as part of the build summary:

The build summary allows us to access the HTML coverage report and shows us the code coverage number.



We can now generate a code coverage report in our build pipeline and spot parts of our code that lacks test coverage. Next week we find out what screws we need to turn so that SonarQube accepts our code coverage report.

1 thought on “Publishing Code Coverage in Your Azure DevOps Build Pipeline”

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.