Visual Studio is excellent, but on personal projects where I’m normally playing around on a low powered laptop and don’t need 99% of the features in Visual Studio, VS Code is my goto. VS Code is so much more than a text editor, out of the box you get a full-fledged debugger, ability to attach to remote machines, Live Share for pair programming and an extension for almost everything. If you’ve not already given it a go I recommend you do (Did I mention LiveShare?).

I was playing around with a new project the other day and went looking for extensions to show my code coverage, after a little setup I had something running, I was really surprised at how well it all hung together.

Coverage Animation

There ended up being 3 parts to this.

  • Continous testing achieved from in the VS Code terminal using dotnet watch.
  • A cmd file building on top of dotnet watch to also generate a code coverage file.
  • The Coverage Gutters VS Code extension to show code coverage within VS Code.

First up let’s create a new solution and a couple of projects. Add a new directory and navigate into it in your terminal then follow the below steps.

  • dotnet new sln -n VsCodeTestWorkFlow
  • dotnet new xunit -o Tests
  • dotnet new classlib -o Lib
  • dotnet sln VsCodeTestWorkflow.sln add .\tests\Tests.csproj
  • dotnet sln VsCodeTestWorkflow.sln add .\Lib\Lib.csproj
  • dotnet add .\Tests\Tests.csproj reference .\Lib\Lib.csproj
  • dotnet add .\Tests\Tests.csproj package coverlet.msbuild

You will now have a new solution with 2 projects, a class library and a test project, the test project is referencing the class library to perform its tests.

Lets now write a quick a FizzBuzz method and stick that in our class library, don’t worry about the implementation, the code below is more than enough for us to write some tests and see coverage information. Add the below as a new method in class1.cs in the lib project.

public string FizzBuzz(int number)
    if (number % 3 == 0 && number % 5 == 0)
        return "FizzBuzz";
    else if (number % 3 == 0)
        return "Fizz";
    else if (number % 5 == 0)
        return "Buzz";
        return number.ToString();

We can use dotnet watch to run our tests whenever a source file changes by running this command

dotnet watch --project .\tests\ test

Watch Test Terminal

The above works really well if you run it within a terminal in VS Code to get fast feedback on your changes within your edtor. Now, let’s take this to the next level and get our code coverage indicators in the gutters of VS Code. The coverlet.msbuild package we installed earlier can generate code coverage files that we can then use an extension in VS Code to read. In order to generate the coverage files we’ll need to tweak our above dotnet watch command slightly.

dotnet watch --project .\Tests\ test /p:CollectCoverage=true /p:CoverletOutputFormat=lcov /p:CoverletOutput=./

I usually put this into a new file called something like Continous-Test.cmd and just run that file from my terminal to avoid having to keep typing it.

Watch Test Terminal

For the next step install the Coverage Gutters extension into VS Code

VS Code Extension

Once that is installed press Ctrl+Shift+P, type coverage and click “Coverage Gutters Watch”, this is now watching the output coverage file generated by our dotnet watch command and is updating the gutters in VS Cove with coverage information as it changes.

Leave the watch from above running and add the following test to UnitTest1.cs

public void ZeroReturnsZero()
    var c = new Class1();
    var result = c.FizzBuzz(0);
    Assert.Equal("FizzBuzz", result);

Within a few seconds the watch will pick this up and you’ll see new coverage information in the terminal.

Terminal Coverage

You’ll also see the gutters in VS Code updated to show what lines in our FizzBuzz method are covered by a test and also if that test is currently passing.

VS Code Gutter Coverage

I’ve been enjoying using VS Code a lot more since getting this setup. It works really well for my workflow, another extension worth looking at is .Net Core Test Explorer which gives you a new window with all the tests and also puts a debug test button above the source code for each test which I use a LOT.