Scott Hanselman

AltCover and ReportGenerator give amazing code coverage on .NET Core

July 20, 2018 Comment on this post [10] Posted in DotNetCore | Open Source
Sponsored By

I'm continuing to explore testing and code coverage on open source .NET Core. Earlier this week I checked out coverlet. There is also the venerable OpenCover and there's some cool work being done to get OpenCover working with .NET Core, but it's Windows only.

Today, I'm exploring AltCover by Steve Gilham. There are coverage tools that use the .NET Profiling API at run-time, instead, AltCover weaves IL for its coverage.

As the name suggests, it's an alternative coverage approach. Rather than working by hooking the .net profiling API at run-time, it works by weaving the same sort of extra IL into the assemblies of interest ahead of execution. This means that it should work pretty much everywhere, whatever your platform, so long as the executing process has write access to the results file. You can even mix-and-match between platforms used to instrument and those under test.

AltCover is a NuGet package but it's also available as .NET Core Global Tool which is awesome.

dotnet tool install --global

This makes "altcover" a command that's available everywhere without adding it to my project.

That said, I'm going to follow the AltCover Quick Start and see how quickly I can get it set up!

I'll Install into my test project hanselminutes.core.tests

dotnet add package AltCover

and then run

dotnet test /p:AltCover=true

90.1% Line Coverage, 71.4% Branch CoverageCool. My tests run as usual, but now I've got a coverage.xml in my test folder. I could also generate LCov or Cobertura reports if I'd like. At this point my coverage.xml is nearly a half-meg! That's a lot of good information, but how do I see  the results in a human readable format?

This is the OpenCover XML format and I can run ReportGenerator on the coverage file and get a whole bunch of HTML files. Basically an entire coverage mini website!

I downloaded ReportGenerator and put it in its own folder (this would be ideal as a .NET Core global tool).

c:\ReportGenerator\ReportGenerator.exe -reports:coverage.xml -targetdir:./coverage

Make sure you use a decent targetDir otherwise you might end up with dozens of HTML files littered in your project folder. You might also consider .gitignoring the resulting folder and coverage file. Open up index.htm and check out all this great information!

Coverage Report says 90.1% Line Coverage

Note the Risk Hotspots at the top there! I've got a CustomPageHandler with a significant NPath Complexity and two Views with a significant Cyclomatic Complexity.

Also check out the excellent branch coverage as expressed here in the results of the coverage report. You can see that EnableAutoLinks was always true, so I only ever tested one branch. I might want to add a negative test here and explore if there's any side effects with EnableAutoLinks is false.

Branch Coverage

Be sure to explore AltCover and its Full Usage Guide. There's a number of ways to run it, from global tools, dotnet test, MSBuild Tasks, and PowerShell integration!

There's a lot of great work here and it took me literally 10 minutes to get a great coverage report with AltCover and .NET Core. Kudos to Steve on AltCover! Head over to and give it a STAR, file issues (be kind) or perhaps offer to help out! And most of all, share cool Open Source projects like this with your friends and colleagues.

Sponsor: Preview the latest JetBrains Rider with its built-in spell checking, initial Blazor support, partial C# 7.3 support, enhanced debugger, C# Interactive, and a redesigned Solution Explorer.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
July 20, 2018 11:55
Hi Scott,

great article.

ReportGenerator is also available as a Global tool, a CLI tool packacke is also available.
They are currently available as "alpha" releases. "alpha" just means that they are not yet feature complete.

I also created a sample project which uses OpenCover, Coverlet and altcover to generate coverage reports:
July 20, 2018 19:40
Is altcover adding IL to the assemblies under test?
Does that mean you should be creating separate artefacts in your
CI pipeline for coverage so as to avoid polluting your release dlls?

Loving this series of articles!
July 22, 2018 4:07

Take a look at minicover and let us know what you think.
Do you know any dotnet core compatible mutation framework that works on any dotnet core supported platform? I am used to pit test on Java platform (thanks to @unclebobmartin).

Kind regards,

Carlos Adriano Portes
July 22, 2018 13:39
I had a play with the source code of NinjaTurtles (
I got stuck when the mutations generated invalid assemblies when replacing conditional jumps.
Maybe I did not understand all the differences associated with the .core version of Cecil.
There is a fork of NinjaTurtles on Github (NinjaTurtlesMutation) that I have not investigated.
July 23, 2018 0:48
+1 on mutation testing. There seems to be no good mutation tools that are supported in vs2017. Ironically with Rosyln this should be the most productive platform to do this for. I always thought this world have been a killer feature that Anders would have brought out as Roslyn was unveiled. @Scott any internal projects brewing for vs2019?
July 24, 2018 3:23
тут на этом интернет-ресурсе [url=][/url] собран огромный ассортимент интересных статей о туризме.
July 24, 2018 16:46
I got stuck when the mutations generated invalid assemblies when replacing conditional jumps.
July 24, 2018 17:51
Great article. Are there any framework that works on any dotnet core supported platform?
July 25, 2018 0:02
I'm stuck trying to pull of a "dotnet tool install".

It is looking at my companies NuGet feed, where as the tool is I guess in the public feed?

So I get some error "unable to load the service index for source", but of course it isn't the correct source...

Any ideas?
I'm stuck and desperate for help.

Thanks in advance!
July 25, 2018 5:12
totally out of topic, but just wanted to say, thanks for this (.net core course in MVA)

i was very hesitant to look ito it given that i just picked up MVC, and some courses over complicate the Core setup, but the tutorial pace from beginner, intermediate, advance is easy to follow and understand, GOOD JOB and thanks.

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.