CLI tool
SteveGilham/altcover avatar
SteveGilham/altcover

altcover: coverage instrumentation for .NET, .NET Core and Mono

Cross-platform coverage gathering and processing tool set for dotnet/.Net Framework and Mono

534 stars22 forksF#MIT

At a glance

What is it?
altcover records code coverage by weaving extra IL into the assemblies before they run, rather than hooking the runtime profiling API, which is what lets it work on Mono and on .NET Core where profiler-based tools were missing. It ships as a command line tool, MSBuild tasks, a PowerShell module and a visualizer, and it is written in F#.
Who is it for?
Adopt altcover if you need code coverage on Mono or on a .NET Core target where profiler-based instrumentation was unavailable, or if you want coverage collection inside FAKE and Cake builds. Do not adopt it if a profiler-based collector already covers your platforms, since weaving is slower and changes the assemblies under test, and do not expect a single global coverage configuration file, because each package ships a different subset of the tooling.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly F#, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Weaving IL instead of hooking the profiler

altcover is an instrumenting coverage tool for .NET, framework 2.0 and later, .NET Core and Mono, and the interesting decision is the mechanism. The README explains it directly: 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.

That single choice explains almost everything about the project. Because the instrumentation is baked into the assembly before it runs, the tool does not need a profiler API to be present, so it works on Mono and on .NET Core as well as on the framework. The cost is that the assemblies under test are modified, which is slower to instrument and changes what is being measured, and it means the executing process needs write access to the results file.

There is a practical bonus to the approach. The README notes that you can mix and match between platforms used to instrument and those under test, so you can record coverage on one machine and process it on another.

The audience is a .NET developer who needs coverage on a platform where the usual tooling did not reach. The project is a reimplementation and extension, almost beyond recognition, of dot-net-coverage, which the same author wrote, plus a set of related utilities for processing results from this and from other programs producing similar output formats.

The primary language is F#, which the README explains in the back-story: the first version was written to fill a functional gap and to give the author an excuse for a ground-up F# project to work on.

What ships in the box, in five NuGet flavours

The package set is unusually granular, and the reason is that the tool is used in three different contexts that need different subsets.

The general purpose AltCover package carries the command line tool for recording coverage, including dotnet and global tool versions, the MSBuild tasks that drive it including dotnet test integration, an API for that functionality with Fake and Cake integration, the PowerShell module for PowerShell 5.1 and PowerShell Core 6+ containing a cmdlet that drives the tool plus other cmdlets for manipulating coverage reports, and the coverage visualizer.

The visualizer itself has two implementations, which is a detail worth knowing before you install. For .NET Framework and Mono it needs GTK# v2.12.xx installed separately, and for .NET Core it uses the cross-platform AvaloniaUI toolkit, which is the one to pick if you want a single visualizer that runs everywhere.

The narrower packages each exclude something. AltCover.api excludes the dotnet test API with the FAKE and CAKE integration and the AvaloniaUI visualizer. AltCover.global is the dotnet global tool install and excludes the visualizer in all forms. AltCover.visualizer is just the .NET Core Avalonia visualizer as a global tool. AltCover.Fake is just the AltCover helper types for FAKE scripts, v5.23.0 or later, and AltCover.Cake is the same for Cake scripts, v2.0.0 or later.

That split is the practical advice: take the general package if you are unsure, and the specific one if your build has a size or dependency budget you care about. It is also why there is no single global configuration file to point at, since what is configurable depends on what is installed.

The Mono symbol limitation that shows up in reports

One limitation is called out with enough detail to be worth reading, because it changes how reports look rather than how coverage is collected.

Instrumenting .NET Core assemblies just works with the weaving approach, and the tool also supports Mono as long as suitable .mdb symbols are available, or .pdb in recent versions. The catch is in the Mono symbol format itself. The .mdb format only stores the start location in the source of any code sequence point, and not the end, so any nicely coloured reports that take that information into account may show a bit strangely.

That is a purely presentational consequence, and it is a good example of the kind of detail that separates a tool that works on a platform from one that works well on it. Coverage counts are unaffected, and the coloured highlighting of source ranges is where the difference shows up.

The same section also names the practical requirement, which is that suitable symbols must be available. That is a build step you own, not something the tool sorts out for you, and it is the first thing to check when a Mono build produces coverage with no useful source mapping.

There is a further boundary in the project's own plans. The README states that legacy framework and Mono support is not going away any time soon, because .NET 4.7.2 can consume netstandard2.0 libraries for everything but the recorder, and .NET Core 2 and later can consume net20 libraries, the recorder. Support continues until those API levels can no longer be retained, and framework-targeted builds are kept to a minimum, limited to executable entry points and the recorder.

A project with a long history and a slow tempo

The back-story is unusual and it tells you how to read the release cadence.

In 2010 a new .NET version removed the deprecated profiling APIs that the free NCover 1.5.x series relied on. The first version of AltCover was written to fill that gap in functionality and, as the README puts it, to give the author an excuse for a ground-up F# project. It saw real production use for about a year and a half, until OpenCover reached a point where it could be used for .NET 4 and x64 work and the author had time to adapt the downstream consumers of NCover format input.

Then in autumn 2017 the project was dusted off, with the intention of showing it worked on Mono, and the author found it was deja vu all over again because .NET Core did not have profiler-based coverage tools either and the same approach would work there too.

The releases carry the same naming. The listed ones are release/9.0.145, Indori series release 3, from 2026-09-08, release/v9.0.102, Indori series release 2, from 2025-11-12, and release/v9.0.1, Indori series release 1, from 2024-11-14.

The project states its own tempo plainly: progress on the author's part will continue to be slow, as this is now much more a side project than the main thing he does to occupy his time in retirement. Tracking the latest dotnet version will continue. That is an unusually candid maintenance statement, and it is the right thing to weigh. The code is not abandoned, the last push was on 2026-10-20, and the project is not archived, but the pace of new features is a side project's pace.

The build is on GitHub Actions with a Coveralls coverage status badge for the project itself, and the roadmap is tracked in GitHub project boards, one for current work and one for long term research items. The README notes that all To do and On Hold items are implicitly up for grabs, and that most of the current items are XML manipulation or GUI programming.

Building altcover from source

The build instructions are short because the repository is largely self-contained, but the tooling requirement is specific.

Two things are assumed to be available on all platforms. The first is the .NET SDK version as per global.json, or a later minor version, invoked as dotnet. The second is PowerShell Core, invoked as pwsh.

The build may target netstandard2.0 or net8.0 for the deliverables and net10.0 for the unit tests, and the README notes that it does not need any pre-10.0 runtimes to be installed because roll-forward policies are in place. That matters for CI images pinned to older runtimes.

The repository layout shows how much is here. There are separate projects for the engine, the recorder, the monitor, the toolkit, the visualizer and its Avalonia front end, the data collector, the PowerShell module, the Cake and Fake integrations, the async helpers, and the UI common code, each with a matching test project, plus a ValidateGendarmeEmulation project whose name alone suggests the emphasis on covering the coverage tool itself. There is Demo/ with several sample projects including an xunit-dotnet one, Samples/ and RegressionTesting/ directories, MCS/ for the Mono side, and a set of PowerShell build scripts including bootstrap.ps1, fullbuild.ps1 and ToolUpdate.ps1.

Getting started for a user, though, does not mean building from source. The README points new users at a Quick Start guide in the wiki and an FAQ, and says the easiest and most automated way to get the latest releases is through the NuGet packages.

Editorial conclusion

Adopt altcover if you need code coverage on Mono or on a .NET Core target where profiler-based instrumentation was unavailable, or if you want coverage collection inside FAKE and Cake builds. Do not adopt it if a profiler-based collector already covers your platforms, since weaving is slower and changes the assemblies under test, and do not expect a single global coverage configuration file, because each package ships a different subset of the tooling. Verify first that the NuGet package matching your target exists, that your platform has the right symbols available, .mdb for Mono or .pdb in recent versions, and that the .NET SDK version satisfies the global.json pin in this repository if you build it from source.

Frequently asked questions

How does altcover collect code coverage?

Instead of hooking the .NET profiling API at run time, it weaves the same sort of extra IL into the assemblies of interest ahead of execution. That is why it works on Mono and on .NET Core as well as on the .NET Framework, as long as the executing process has write access to the results file.

Which NuGet package should I install for altcover?

The general purpose AltCover package carries the CLI, MSBuild tasks, the API, the PowerShell module and the visualizer. Narrower packages exist for the API only, the dotnet global tool, the Avalonia visualizer alone, and the FAKE and Cake helper types, each excluding something from the full set.

Does altcover work with Mono?

Yes, as long as suitable .mdb symbols are available, or .pdb in recent versions. The README notes a limitation in that path, since the .mdb format only stores the start location of a code sequence point and not the end, so coloured reports that use that information may show a bit strangely.

What does altcover integrate with for build and scripting?

It ships MSBuild tasks including dotnet test integration, an API with Fake and Cake integration, a PowerShell module for PowerShell 5.1 and PowerShell Core 6+ with a cmdlet that drives the tool, and separate NuGet packages holding just the FAKE and Cake helper types.

What are the recent altcover releases and how fast do they come?

The listed releases are release/9.0.145, Indori series release 3, from 2026-09-08, release/v9.0.102 from 2025-11-12, and release/v9.0.1 from 2024-11-14. The README states that progress will continue to be slow because the project is now a side project, and that tracking the latest dotnet version will continue.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. SteveGilham/altcover on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/stevegilham-altcover.svg)](https://hysenlabs.com/projects/stevegilham-altcover)

Was this useful?