This blog post will save you time and effort by providing you with all the information you need for creating software tests with XUnit, so that you do not have to collect this information from disparate sources. It details creating the test projects, specifies what nuget packages are required, how to write and run the tests and how to send information to the test console.
For an article that treats Test Driven Development from the architectural point of view and in much more detail, please see Test Driven Development Process with XUnit.
Most console programs have single Main()
method to run. Testing frameworks allow you to run multiple methods called Tests. Each such method usually correspond to testing a certain feature.
XUnit is one of the most popular .NET testing frameworks. Its test methods are marked with [Fact]
or [Theory]
attribute ([Theory]
allows you to run the same method multiple times with different arguments).
To make it possible to run [Fact]
s and [Theory]
s in Visual Studio you create the your testing project as a class library and add xunit nuget package to it.
To make it possible to debug [Fact]
s and [Theory]
s in Visual Studio you have to add two more nuget packages: Microsoft.NET.Test.SDK and xunit.runner.visualstudio:
To run or debug the tests you should open the test explorer from the Visual Studio:
Then find the test you want to run in it and press Run or Debug button:
If you use debug, the execution will stop once a breakpoint is hit.
The code for the very simple XUnit samples is located under XUnitSample project on github.com.
File XUnitTests.cs contains two tests of built-in .NET method string.Split() - one to demonstrate [Fact]
and another - [Theory]
.
Here is the Fact
sample:
// fact sample
[Fact]
public void TestSplit()
{
string str = "Hello World";
string[] split = str.Split(' ', StringSplitOptions.RemoveEmptyEntries);
// assert that the split is a collection of two strings:
// "Hello" and "World"
Assert.True(split.SequenceEqual(["Hello", "World"]));
}
We split string "Hello World" into an array containing two strings - "Hello" and "World" and we assert that the result is correct.
Here is the code for [Theory]
test:
/// <summary>
/// Run TestSplits(...) methods for every [InlineData]
/// providing various arguments.
/// </summary>
[Theory]
[InlineData("Hello", new string[] { "Hello" })]
[InlineData("Hello World", new string[] { "Hello", "World" })]
[InlineData("Hello Great World", new string[] { "Hello", "Great", "World" })]
public void TestSplits(string strToSplit, string[] expectedSplit)
{
string[] split = strToSplit.Split(' ', StringSplitOptions.RemoveEmptyEntries);
Assert.True(split.SequenceEqual(expectedSplit));
}
TestSplits(...)
method has two arguments:
-
stringToSplit
- is the original string to be splitted -
expectedSplit
- argument containing the array with the expected result of the split.
The [InlineData]
attributes provide both arguments to the TestsSplits(...)
method. Since there are three [InlineData]
attributes - the TestsSplits(...)
method will be run three times (for each set of arguments).
There is also XUniTestWithPrinting.cs file. It demonstrate how to create tests that print information you want to the test console (the usual Console.WriteLine(...)
methods will not work). All you need to do is to provide a constructor taking an argument of ITestOutputHelper
type and assign the value of this argument to a property or a field of the class:
public class XUnitTestWithPrinting
{
private ITestOutputHelper _xunitOutput;
/// <summary>
/// pass a test console writer for the test
/// (XUnit will provide the correct value itself)
/// </summary>
/// <param name="xunitOutput"></param>
public XUnitTestWithPrinting(ITestOutputHelper xunitOutput)
{
_xunitOutput = xunitOutput;
}
...
}
Then you can use this property of field to print to the test console as it is done in XUnitTestWithPrinting.TestSplit()
method:
[Fact]
public void TestSplit()
{
string str = "Hello World";
string[] split = str.Split(' ', StringSplitOptions.RemoveEmptyEntries);
Assert.True(split.SequenceEqual(["Hello", "World"]));
foreach (string part in split)
{
// print each part to Test Console
_xunitOutput.WriteLine(part);
}
}
The results will be shown in the TestExplorer window on the right:
Top comments (0)