Debugging Dotnet Core Projects with Visual Studio Code

Including Debugging Those Pesky Test Projects

Originally I was just going to do a quick write-up for debugging a test project, but I figured, what the heck let’s just do one for debugging all of the things.

I’m using Dotnet Core 2.0 right now and recommend upgrading to it if you’re not using it as well — the tooling feels much more mature now compared to a few months ago when I was using 1.1.

Setup

Make a solution with a simple console application and a mstest project (you can use xunit if you prefer that). Once you have those configured, open up Visual Studio code and navigate to the debug tab. Click on the little gear icon to create a new launch configuration — select “.Net Core” from the dropdown.

You’ll have to modify the launch.json file that get’s created a little bit to get up and running. In the console configuration, make sure you point the “program” setting to the console project. You can delete the web configuration — we won’t need it. This is what mine looks like:

launch.json

Next we’ll have to configure a task runner. Press the green play button and click on “Configure Task Runner” when prompted. Again, select “.Net Core” from the dropdown. You shouldn’t have to modify this file at all.

Debugging Non-test Projects

Now that the project and debugger is all set up we’re pretty much done with debugging non-test projects. This will work with web projects, console applications, and class libraries that are included in other executable projects.

Place a breakpoint in a file, go to the debug tab, and press play. Here I’ll just be using the file that came with the console application.

Debugging a Non-test Project

And there we have it. Like I said earlier this works exactly the same for applications more complicated than printing “Hello World!”, allowing you to step through code and watch variables as you would expect.

Debugging Test Projects

Trying to do this is what pushed me to do this write up. There was no clear documentation for how to enable debugging in a test project with Dotnet Core in Visual Studio Code. I was really surprised given how intutive it is in Visual Studio. I realize there’s a little button to debug the test if you have the Omnisharp extension, but it was full of lies for me and didn’t work.

To start I’m going to make a class we can use in the console purely for the sake of having something to unit test.

A little Printer class we can debug

And now that I have that I’m going to fill in the unit test included with the test project.

A simple unit test

If you run the test (using dotnet test) you’ll see that it passes as we would expect. The problem we have now is that there’s no obvious way to try and debug this test — we only have debug configurations for the console application, and then a configuration to attach a debugger to a process. Even if we put a breakpoint in our tests right now, they will be ignored because we’re not running debug mode.

We’re going to use the configuration for attaching a debugger, but we have to set an environment variable that will enable debugging tests hosted on the dotnet test process.

On Mac/Linux:

export VSTEST_HOST_DEBUG=1

On Windows (using Powershell)

$env:VSTEST_HOST_DEBUG=1

Now if you run the test again you’ll see a prompt to attach a debugger to the test process. Navigate to the debug tab and select the “.NET Core Attach” configuration from the dropdown. Press the green play button and select the process that is indicated by the prompt.

Attaching a debugger to the test process

Once the degbugger attaches you’ll have to press the play button again on the debug bar that appears. You should now see that the breakpoint has been caught by the debugger and you can now step through code, watch variables, etc.

The only caveat with this is that you will need to disable debugging the tests if you want to run the tests without having to attach a debugger every time.

On Mac/Linux:

export VSTEST_HOST_DEBUG=0

On Windows (using Powershell)

$env:VSTEST_HOST_DEBUG=0

Conclusion

Debugging tests is an extremely important tool to have in your development toolbelt. I am disappointed with the extra work that has to go into making a debugger accessible in test projects, but in the end it is worth the utility it provides.

I put all the code I wrote for this post in this repository on my GitHub. Feel free to take a look.