2020-03-09

Unit test coverage in Visual Studio for Mac

I've recently started working on a new project using Visual Studio for Mac to write apps for iOS and Android in C#. I'll try to write about this new project in the future, but for now I wanted to talk about measuring and viewing code coverage for my unit tests.

Although Visual Studio for Windows does have code coverage measurements and reporting built-in, VS for Mac does not. It does support running unit tests, via NUnit or xUnit, but only shows information about tests passing or failing.

I did a bit of searching about found the VSMac-CodeCoverage extension for VS, but when I tried it install it failed. It looks like there has been a new release which may solve that, but I haven't had a chance to try yet. [Update: that extension has been fixed and does work now.]

Because the above extension didn't work for me when I tried, I can up with a different usable solution. It isn't perfect, but it does allow me to run my tests, generate a code coverage report, and view it as HTML with a single menu option. Here's what I did:

  1. In your unit tests project add the following two nuget packages:
    1. coverlet
    2. ReportGenerator
  2. Verify that you can run tests from the command line by running this in the folder of your unit tests project:
    dotnet test --collect:"XPlat Code Coverage"
  3. Verify that you can generate reports from the command line:
    ~/.dotnet/tools/reportgenerator -reports:TestResults/0cf0a5da-b2a9-46b1-9fe8-78ae83743fd7/coverage.cobertura.xml -targetdir:CoverageReport
    The long ID will be different for each test run.
    Then view the generated report:
    open CodeCoverage/index.htm
  4. If the above worked, then you just need to script to semi-automate this. Here's my script:
    #!/bin/zsh
    dotnet test --collect:"XPlat Code Coverage"
    ~/.dotnet/tools/reportgenerator -reports:TestResults/`ls -1t TestResults | head -1`/coverage.cobertura.xml -targetdir:./CodeCoverage
    open CodeCoverage/index.htm
  5. Finally, add a custom tool to the Tools menu: Tools → Edit Custom Tools...
You can then run the tests to generate coverage data, generate the coverage report, and open it in your browser just by running this new command from the Tools menu. Note that you must run the command when one of your unit test files is opened because it uses the ${ProjectDir} as the working directory and the unit test runner must run in a unit test project.