Writing tests for ASP.NET Core applications can be done using xUnit. xUnit works on both.NET Framework and .NET Core. This post shows how to set up and use xUnit with ASP.NET Core applications in Visual Studio and on command-line. Targeting multiple frameworks is also covered.
Adding xUnit to solution
We want to run xUnit tests from command line using dotnet utility and we would also like to use Visual Studio Test Explorer for running tests in dev boxes. For this we have to add the following package references to project.json file of tests project:
- xunit
- xunit.runner.dnx
- dotnet-test-xunit
In the beginning of project.json file we also have to specify the test runner to use. For this there’s testRunner attribute. Here’s my current project.json.
“version”: “1.0.0-*”,
“testRunner”: “xunit”,
“dependencies”: {
“Microsoft.NETCore.App”: {
“version”: “1.0.1”,
“type”: “platform”
},
“xunit”: “2.1.0”,
“xunit.runner.dnx”: “2.1.0-rc1-build204”,
“dotnet-test-xunit”: “2.2.0-preview2-build1029”,
“AdvancedAspNetCore.Testing”: “1.0.0”,
“System.Runtime”: “4.1.0”
},
“frameworks”: {
“netcoreapp1.0”: {
“imports”: [
“dnxcore50”,
“portable-net45+win8”
]
}
}
}
In dependencies section there is also reference to web application projectection. More about project.json can be found from project.json reference.
Writing simple tests
Now let’s write some simple dummy tests. I don’t focus here on what to test and how to do it in real scenarios. Here I just want to show how things work. So, here is my simple and primitive test class.
using AdvancedAspNetCore.Testing.Controllers;
using Microsoft.AspNetCore.Mvc;
using Xunit;
namespace AdvancedAspNetCore.Testing.Tests
{
public class HomeControllerTests
{
public HomeControllerTests()
{
}
[Fact(DisplayName = “Index should return default view”)]
public void Index_should_return_default_view()
{
var controller = new HomeController();
var viewResult = (ViewResult)controller.Index();
var viewName = viewResult.ViewName;
Assert.True(string.IsNullOrEmpty(viewName) || viewName == “Index”);
}
[Fact(DisplayName = “Failing test”)]
public void ShouldFail()
{
throw new NotImplementedException();
}
}
}
The first test checks if Index() method of home controller returns view with empty name or with name “Index”. Second test just fails immediately with exception.
Running tests in Visual Studio
To run tests in Visual Studio we select Tests from top menu and then Run and All Tests like shown on image below.
Note how Test Explorer is using nice names for tests. In code above we used DisplayName parameter with Fact attribute and this is where nice names of tests are taken.
Running xUnit tests on command-line
When building application on build server or some CI server or – why not – in Linux we want to run tests on command-line. For this we can use dotnet utility. To run tests on command-line we open console and move to tests project folder. There we run the following command:
dotnet test
It produces console output like this:
It’s perhaps good enough if we run tests manually and read the results but it’s not enough if we want to get out something that is okay for reporting. This is specially the case with CI servers with web interface. We are lucky because xUnit supports also XML-output. All we need is the following command:
dotnet test –xml results.xml
As a result we get same console output but results are also written to results.xml file. Here’s the content of this file in our case.
<assemblies>
<assembly name=“AdvancedAspNetCore.Testing.Tests.dll“
environment=“64-bit .NET (unknown version) [collection-per-class, parallel (4 threads)]“
test-framework=“xUnit.net 2.1.0.3179“ run-date=“2016-10-26“ run-time=“12:13:07“ total=“2“
passed=“1“ failed=“1“ skipped=“0“ time=“0.208“ errors=“0“>
<errors />
<collection total=“2“ passed=“1“ failed=“1“ skipped=“0“
name=“Test collection for AdvancedAspNetCore.Testing.Tests.HomeControllerTests“ time=“0.050“>
<test name=“Index should return default view“ type=“AdvancedAspNetCore.Testing.Tests.HomeControllerTests“
method=“Index_should_return_default_view“ time=“0.0493443“ result=“Pass“ />
<test name=“Failing test“ type=“AdvancedAspNetCore.Testing.Tests.HomeControllerTests“ method=“ShouldFail“
time=“0.0006822“ result=“Fail“>
<failure exception-type=“System.NotImplementedException“>
<message><![CDATA[System.NotImplementedException : The method or operation is not implemented.]]></message>
<stack-trace><![CDATA[ at AdvancedAspNetCore.Testing.Tests.HomeControllerTests.ShouldFail() in D:\Projects\AdvancedAspNetCore\AdvancedAspNetCore\AdvancedAspNetCore.Testing.Tests\HomeControllerTests.cs:line 28]]></stack-trace>
</failure>
</test>
</collection>
</assembly>
</assemblies>
This XML is simple enough to generate HTML output of it.
Running xUnit tests for multiple runtimes
Now let’s see what happens if our web application targets multiple .NET Framework versions. Suppose we want application to run on .NET Core and .NET Framework 4.6. We have to add .NET Framework 4.6 to supported list of frameworks (in web application and test project). Here’s our new project.json for tests project.
“version”: “1.0.0-*”,
“testRunner”: “xunit”,
“dependencies”: {
“xunit”: “2.2.0-beta3-build3402”,
“dotnet-test-xunit”: “2.2.0-preview2-build1029”,
“AdvancedAspNetCore.Testing”: “1.0.0”
},
“frameworks”: {
“netcoreapp1.0”: {
“dependencies”: {
“Microsoft.NETCore.App”: {
“version”: “1.0.1”,
“type”: “platform”
},
“xunit.runner.dnx”: “2.1.0-rc1-build204”,
“System.Runtime”: “4.1.0”
},
“imports”: [
“dnxcore50”,
“portable-net45+win8”
]
},
“net46”: {
“dependencies”: {
“xunit.runner.visualstudio”: “2.2.0-beta3-build1187”
}
}
}
}
Let’s run dotnet test again and see the console output.
NB! When writing this post the XML-output of xUnit doesn’t reflect results for all tested frameworks. It seems like only the first one gets to XML-file.
Wrapping up
xUnit is matured testing framework that works also with ASP.NET Core and .NET Core. Although all work is not finished yet it seems most important parts of xUnit already work well with ASP.NET Core. It’s possible to run tests in Visual Studio Test Explorer and on command-line. For applications targeting multiple frameworks tests are run for every supported framework. Although XML-output doesn’t reflect it yet it works fine with console output. xUnit doesn’t come with any complex requirements and it is possible to run it also on build and CI servers.
View Comments (8)
It would be nice to have a viewer for OSX.
If you are writing code on VS Code then please check out if OmniSharp extension for VS Code helps you.
oh, thank you!
I played with VS Code on Linux last night. There is test runner for nUnit available. I found nothing for xUnit. To visualize xUnit tests you can write script that runs tests with XML-output, then applies XLS-transform to generate HTML and then opens HTML report in browser. Also it should not be hard to write VS Code extension for it.
Hi Gunnar, I'm trying to work in VS 2015 with this at the minute and getting a few errors. Any idea what I should be using as things seem to have changed since your post above? Many thanks!
Hi, Declan! What errors you get exactly?
Hi Gunnar, I created the solution and test in VS 2019 works exactly as expected but not on the command line. When I issue
dotnet test -xml results.xml
I get the following error right away
MSBUILD : error MSB1001: Unknown switch.
Switch: -xml
-xml results.xml worked with previous versions of xUnit. Now you should use --logger "xunit;LogFileName=TestResults.xml".