Code Coverage Reports for ASP.NET Core
Code Coverage Reports for ASP.NET Core
Code coverage reports for ASP.NET Core projects are not provided out-of-the-box, but by using the right tools we can build decent code coverage reports.
Join the DZone community and get the full member experience.Join For Free
Code coverage reports for ASP.NET Core projects are not provided out-of-the-box, but by using the right tools we can build decent code coverage reports. I needed code coverage reports in some of my projects and here is how I made things work using different free libraries and packages.
To get started, we need a test project and some NuGet packages. Test project can be a regular .NET Core library project. Adda reference to web application project and write some unit tests if you start with a new test project. We also need some NuGet packages to make things work:
- ReportGenerator by Daniel Palme
Note: In the project file, we need a tool reference to run the report generator using the dotnet utility:
<DotNetCliToolReference Include="dotnet-reportgenerator-cli" Version="x.y.z" />
After adding these packages it's time to make a test build and see if everything still works and we don't have any build issues.
Creating Reporting Folders
Now it's time to configure reporting. I decided to keep reports in the BuildReports folder of the test project. There are two subfolders:
- Coverage - for coverage reports.
- UnitTests - unit tests reports (for future use).
I also added the BuildReports folder to the .gitignore file because I don't want these files to wander from one developer box to another and be part of commits.
The number of files in the Coverage folder is not small. It's not just two or three files that are easy to ignore. There can be hundreds or thousands of files depending on how many tests there are in test projects. Here we are working on a smaller scale, of course.
Getting Code Coverage Data
To generate reports we need coverage data and this is why we added the
coverlet.msbuild package to the test project. When tests are run, we gather code coverage information and publish it in the Cobertura output format. Cobertura is a popular code coverage utility in the Java world. Test data is transformed to the Cobertura format by Coverlet — a cross platform code coverage library for .NET Core.
With coverage data, I also output unit test results in Microsoft and xUnit formats to the UnitTests folder. As I said before, this is for future use and we don't do anything with files in these folders right now.
I added the run-tests.bat file to the root folder of my test project and the first command there is for running unit tests (in your file you can put it all in one line without any line breaks).
dotnet test --logger "trx;LogFileName=TestResults.trx" --logger "xunit;LogFileName=TestResults.xml" --results-directory ./BuildReports/UnitTests /p:CollectCoverage=true /p:CoverletOutput=BuildReports\Coverage\ /p:CoverletOutputFormat=cobertura /p:Exclude="[xunit.*]*
This is what this command does:
- Using Visual Studio logger to create the TestResults.trx file for test results.
- Using the xUnit logger create the TestResults.xml file for test results.
- Put test results in the ./BuildReports/UnitTests folder.
- Enable collecting of code coverage data.
- Make Coverlet use the BuildReports\Coverage folder.
- Set Coverlet's output format to Cobertura.
- Excude xUnit libraries from test results.
As a result of this command, we will have three files:
- BuildReports\UnitTests\TestResults.trx (not important now).
- BuildReports\UnitTests\TestResults.xml (not important now).
- coverage.cobertura.xml (coverage results in Cobertura format).
It's time to try out run-tests.bat to see if everything still works and if files generated to the expected locations.
Generating Code Coverage Reports
For code coverage reports we need to add another command to the run-tests.bat file. This command will run the report generator that generates reports based on the coverage.cobertura.xml file. The reports are generated to the same folder to keep the folder tree smaller.
Here is the command (you can put it all on one line):
dotnet \reportgenerator "-reports:BuildReports\Coverage\coverage.cobertura.xml" "-targetdir:BuildReports\Coverage" -reporttypes:HTML;HTMLSummary
I think this command is not very cryptic and I don't make additional comments on command line parameters here.
As a lazy guy, I expect the browser to automatically open with the newly generated reports and this is why the last line of my run-tests.bat file is:
It's time to run the script and see if it runs successfully to the end.
Code Coverage on Linux
On Linux, we need shell scripts to run tests and generate reports. Here's sample script for Linux (every command goes to one line):
#!/bin/sh sudo dotnet test --logger 'trx;LogFileName=TestResults.trx' --logger 'xunit;LogFileName=TestResults.xml' --results-directory ./BuildReports/UnitTests /p:CollectCoverage=true /p:CoverletOutput=BuildReports/Coverage/ /p:CoverletOutputFormat=cobertura /p:Exclude='[xunit.*]*' sudo dotnet reportgenerator -reports:BuildReports/Coverage/coverage.cobertura.xml -targetdir:BuildReports/Coverage -reporttypes:"HTML;HTMLSummary"
Not sure why tooling needs
sudo, but this is what is asked for. This shell script may also need to execute permissions. Here's the command for this:
chmod +x run-tests.sh
Now we are good to go on Linux too.
Code Coverage Reports
After running the batch file in my playground test project folder, I see the following report in the browser.
The report is longer than we can see here but I'm still not very happy with it. I would like to have a better structural view of the tested code, so I have a better overview of how well the different system areas are covered with tests. Let's take a look at this grouping in the above tests and try to move it. Voila!
To see an overall view of the system under test, I can click and close those bold namespaces. Now we see how much one or another namespace is covered.
We can also go inside classes and see coverage statistics about specific classes. The nice thing is that we get also method-based statistics and the source code view shows us which lines in the class are covered with tests and which lines are not covered.
I think this kind of code coverage reporting is good enough for me.
The path to code coverage reporting is not always easy but I got it to work as expected. All the tools I used are free and incurred no hidden expenses (besides my own time). We had to write a batch file to run tests, collect code coverage data, and generate reports. In the end, we got decent reports giving us a good overview of code coverage of our codebase.
Published at DZone with permission of Gunnar Peipman , DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.