Code Coverage in .NET Core
- Posted in
One of the best things you could do in software is unit testing. There are tons of articles, including mine, explaining why people should take the time to write code in a way that makes it easily split into independent parts that then can automatically tested. The part that is painful comes afterwards, when you've written your software, put it in production and you are furiously working for the second iteration. Traditionally, unit tests are great for refactorings, but when you are changing the existing code, you need not only to "fix" the tests, but also cover the new scenarios, allow for changes and expansions of existing ones.
Long story short, you will not be able to be confident your test suite covers the code as it changes until you can compute something called Code Coverage, or the amount of your code that is traversed during unit tests. Mind you, this is not a measure of how much of your functionality is covered, only the lines of code. In Visual Studio, they did a dirty deed and restricted the functionality to the Enterprise edition. But I am here to tell you that in .NET Core (and possibly for Framework, too, but I haven't tested it) it's very easy to have all the functionality and more even for the free version of Visual Studio.
These are the steps you have to take:
- Add coverlet.msbuild NuGet to your unit tests project
- Add ReportGenerator NuGet to your unit tests project
- Write a batch file that looks like
@ECHO OFF REM You need to add references to the nuget packages ReportGenerator and coverlet.msbuild IF NOT EXIST "..\..\packages\reportgenerator" ( ECHO You need to install the ReportGenerator by Daniel Palme nuget EXIT 1 ) IF NOT EXIST "..\..\packages\coverlet.msbuild" ( ECHO You need to install the coverlet.msbuild by tonerdo nuget EXIT 1 ) IF EXIST "bin/CoverageReport" RMDIR /Q /S "bin/CoverageReport" IF EXIST "bin/coverage.opencover.xml" DEL /F "bin/coverage.opencover.xml" dotnet test "Primus.Core.UnitTests.csproj" --collect:"code coverage" /p:CollectCoverage=true /p:CoverletOutputFormat=\"opencover\" /p:CoverletOutput=\"bin/coverage\" for /f "tokens=*" %%a in ('dir ..\..\packages\reportgenerator /b /od') do set newest=%%a "..\..\packages\reportgenerator\%newest%\tools\netcoreapp3.0\ReportGenerator.exe" "-reports:bin\coverage.opencover.xml" "-targetdir:bin/CoverageReport" "-assemblyfilters:-*.DAL*" "-filefilters:-*ServiceCollectionExtensions.cs" start "Primus Plumbing Code Coverage Report" "bin/CoverageReport/index.htm"
and save it in your unit test project folder
- Optional: follow this answer on StackOverflow to be able to see the coverage directly in Visual Studio
Notes about the batch file:
- newest is the current version of ReportGenerator, if that doesn't work, change it with whatever version you have (ex: 4.3.0)
- the DAL filter tells the report to ignore projects with DAL in their name. You shouldn't have to unit test your data access layer.
- the ServiceCollectionExtensions.cs filter is for files that should be ignored, like extension methods rarely need to be unit tested
Running the batch should start dotnet test and save the result in both coverage.opencover.xml and also some files in the TestResults folder. Then ReportGenerator will generate an html file with the coverage report that will get open at the end. However, if you followed the optional answer, now you are able to open the files in TestResults and see what parts of your code are covered when opened in the Visual Studio editor! I found this less useful than the HTML report, but some of my colleagues liked the option.
I hope this helps you.
Be the first to post a comment