Unit testing with .NET Core

.NET Core has been in production (RTM) since June 2016, when it was officially released at the Red Had Summit by Scott Hanselman. What a glorious moment! Announcing an open source framework at a conference for Linux! Who would have thought that this would be possible 3 years ago?

.NET Core may be in RTM but it's still moving at a very fast pace and there are still a lot of changes to the framework. The team announced ago .NET Standard 2.0 which comes with a few breaking changes. On top of that the tooling around .NET Core is still in beta. And so are a lot of 3rd party libraries. But we are getting there, bit by bit and there's no denying that .NET Core is one of the most exciting technologies released in the recent years.

There are already plenty of apps being written with .NET Core and an integral part of any development CI/CD is unit testing. Testing in .NET Core is one of these things that has proved challenging, more so with the tooling rather than the frameworks. Early on, the team decided to adopt the open source xUnit framework to test .NET Core and ASP.NET Core and also as tool of choice for running tests on top of .NET Core. It’s still the default/preferred option for creating unit tests out of the box.

But for those developers/teams that have invested heavily on other test frameworks such as MSTest and nUnit, this presented a challenge since they would have to rewrite all the unit tests for any migrated application. Luckily, we didn’t get to this and now you can choose the tool that best meets your needs (existing codebase) or style. In this post I’ll show you how you can use the 3 big test frameworks to provide the necessary platform to write your unit tests.

Referencing your libraries in your tests

Before you create your unit tests, you need to reference the code that needs to be tested. Since in .NET Core everything referenced needs to be a NuGet package, we need to use the .NET Core CLI to pack our dependencies and get them ready for sharing. Visual Studio is great in doing this behind the since when we need to reference a .NET Core library in our solution. The steps below show how to do the same (packaging) manually,

cd mylib  
dotnet pack  

We will assume that mylib is your class library. You’ll need to do this for all the code you need to reference. Once you’ve packaged everything, open and edit the target project.json file so that it looks like this:

"dependencies": {
    "mylib": {"target": "project", "version": "1.0.0-*"}
}

Obviously, you’ll need to change myLib to the name of your class library and you’ll need to make sure you’ve changed the version to match your library’s version (if different). The important bit is "target": "project" which instructs the dotnet command to fetch the NuGet package from the current solution instead of the official NuGet feed. Failure to add this, may result in dependencies not resolving properly. You’ll need to repeat the process for all libraries you wish to test (hopefull all of them, right? RIGHT?)

Testing with XUnit

This is the default choice and the one best supported by most tools. Since .NET Core is open source and cross platform, I plan to use the CLI (dotnet commands) for the purpose of this post. I’ll do my best to stay objective for your benefit :D
To add a unit test to your application, create a new folder at the root of your .NET Core application and change into it

mkdir myxunittests  
cd myxunittests  
dotnet new -t xunittest  
dotnet restore  

This command should create one class file with some boilerplate tests and the much needed project.json. The dotnet restore will fetch the necessary depencencies from NuGet. For completeness, your project.json should look like this (should you choose to add the dependencies manually):

{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable"
  },
  "dependencies": {
    "System.Runtime.Serialization.Primitives": "4.1.1",
    "xunit": "2.1.0",
    "dotnet-test-xunit": "1.0.0-rc2-192208-24"
  },
  "testRunner": "xunit",
  "frameworks": {
    "netcoreapp1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.1"
        }
      },
      "imports": [
        "dotnet5.4",
        "portable-net451+win8"
      ]
    }
  }
}

The important bits are the "dependencies":{...} which bring the xUnit framework and its corresponding test runner and the "testRunner":"xunit" which tells our CLI that we are using xUnit for our tests. Without further ado, you can run the dotnet test command and you should an output similar to this:

Testing with MSTest

You asked and the team delivered. MSTest is fully supported in .NET Core and it’s as easy to setup as xUnit. However, there’s no template for it in the CLI (for now?) so the easiest way to get started is to follow the steps for creating an xUnit project and then change the necessary code to make it work with MSTest. In this instance, open and change the project.json file in your test project to look like this:

  "testRunner": "mstest",
  "dependencies": {
    "dotnet-test-mstest": "1.1.1-preview" ,
    "MsTest.TestFramework": "1.0.4-preview"
  },

These are the only sections that you need to change. A reference to the MSTest test framework and the corresponding test runner. Make sure you run dotnet restore to resolve all the dependencies. You can then write your test classes and methods. When ready, you can issue the dotnet test command. In return, you’ll be rewarded with something that should look like this:

Testing with nUnit

Last but not least, **nUnit is supported in .NET Core albeit it's still in beta (at the time of writing this). I've tested it in a few scenarios and works as expected so you should be able to use it with the same reservations as for any other beta library. There are no templates in the CLI so, as with MStest, your best bet is to start by creating an xUnit project. Open and edit project.json as per below:

  "testRunner": "nunit",
  "dependencies": {
        "NUnit": "3.4.1",
        "dotnet-test-nunit": "3.4.0-beta-2",
        "mylib" :  {"target": "project", "version":"1.0.0-*"}
    },

Save and run dotnet restore to resolve all the dependencies. Once NuGet's done, you can go ahead
and write your tests. To run the tests, we need issue the familiar dotnet test command. If all goes well, you should see the following output in the command line:

As an added bonus, nUnit also outputs a TestResult.xml file with a summary of the test run.

Summary

There you have it. 3 different .NET Core test frameworks that allow you to test your code in the same, consistent and performant way. I'm not a big fun of IDEs these days so the more I get to do from the command line the better (it even feels faster). And .NET Core makes it super easy to work from the command line, so an added bonus to an already impressive framework.

I've added a small sample .NET Core project with 3 different tests on GitHub if you want to clone and test it out.

Feel free to leave a comment if you have any questions or suggestions.


  • Share this post on
comments powered by Disqus