How do I use xUnit.net?

This page contains basic instructions on how to use xUnit.net. If you are an existing user of NUnit 2.x or MSTest (the Visual Studio unit testing framework), you should see our comparisons with existing frameworks page.

Writing and Running Your First Test

  • Create a Class Library project to hold your tests (we will assume it is called "MyTestLibrary").
  • Add a reference to the xunit.dll assembly.
  • Add a class to hold your first test class (here we call it "MyTests"). Here is an example test:
using Xunit;

public class MyTests
{
    [Fact]
    public void MyTest()
    {
        Assert.Equal(4, 2 + 2);
    }
}
  • Compile your project, and ensure it compiles correctly.
  • From the command line, run the following command: xunit.console MyTestLibrary.dll (Note: if xunit.console.exe is not in your path, you may need to provide a full path name to it in the command line above). You should see output like this:
C:\MyTests\bin\Debug> xunit.console MyTestLibrary.dll
xUnit.net console test runner (64-bit .NET 2.0.50727.0)
Copyright (C) 2007-11 Microsoft Corporation.

xunit.dll:     Version 1.9.1.0
Test assembly: C:\MyTests\bin\Debug\MyTestLibrary.dll

1 total, 0 failed, 0 skipped, took 0.302 seconds
  • Success!
The Assert class is provided by xUnit.net and contains various methods that can be used to ensure that your test data is valid.

When you run the console runner and pass your library DLL name, the runner loads the DLL and looks for all the methods decorated with the [Fact] attribute and runs them as unit tests. If you want to add more tests, simply add more methods to your test class, or even start new test classes!

When a Test Fails

If a test fails, the xUnit.net console runner will tell you which test failed and where the failure occurred. The failure might be because of a bad assertion:

[Fact]
public void BadMath()
{
    Assert.Equal(5, 2 + 2);
}
Which shows output like this:

MyTests.BadMath [FAIL]
   Assert.Equal() Failure
   Expected: 5
   Actual:   4
   Stack Trace:
      C:\MyTests\MyTests.cs(8,0): at MyTests.BadMath()

The message clearly shows what happened ("Assert.Equal() Failure"), the expected and actual values, and the stack trace of where the failure occurred.

Your test will also fail if an unexpected exception occurs, such as:

[Fact]
public void BadMethod()
{
    double result = DivideNumbers(5, 0);

    Assert.Equal(double.PositiveInfinity, result);
}

public int DivideNumbers(int theTop, int theBottom)
{
    return theTop / theBottom;
}
When run, you should see output like:

MyTests.BadMethod [FAIL]
   System.DivideByZeroException : Attempted to divide by zero.
   Stack Trace:
      C:\MyTests\MyTests.cs(15,0): at MyTests.DivideNumbers(Int32 theTop, Int32 theBottom)
      C:\MyTests\MyTests.cs(8,0): at MyTests.BadMethod()

1 total, 1 failed, 0 skipped, took 0.274 seconds

Obviously, we must've thought that DivideNumbers used doubles instead of ints! :)

What if I Expected an Exception?

In the example above, what if I wanted to write a test to show I was expecting an exception to be thrown? You can use the Assert.Throws method:

[Fact]
public void DivideByZeroThrowsException()
{
    Assert.Throws<System.DivideByZeroException>(
        delegate
        {
            DivideNumbers(5, 0);
        });
}

public int DivideNumbers(int theTop, int theBottom)
{
    return theTop / theBottom;
}
When this test runs, it passes. Note that Assert.Throws requires you to specify the exact exception you're expecting. If the code throws any other exception, even one that's derived from the one you're expecting, it's still a failure. Additionally, if you want to inspect the values of the exception object, Assert.Throws returns the exception object as a return value for you to do further assertions on.

Skipping a Test

Sometimes you will need to temporarily skip a test. The [Fact] attribute has a Skip parameter which can be used to skip the test and show the reason it's being skipped.

[Fact(Skip="Can't figure out where this is going wrong...")]
public void BadMath()
{
    Assert.Equal(5, 2 + 2);
}
When you run this test with the console runner, you should see output like:

MyTests.BadMath [SKIP]
   Can't figure out where this is going wrong...

1 total, 0 failed, 1 skipped, took 0.000 seconds

Ensuring a Test Does Not Run Too Long

The [Fact] attribute contains a parameter named Timeout, which can be used to specify that a test must finish completely within the given time (in milliseconds).

[Fact(Timeout=50)]
public void TestThatRunsTooLong()
{
    System.Threading.Thread.Sleep(250);
}
When you run this test, you should see output similar to this:

MyTests.TestThatRunsTooLong [FAIL]
   Test execution time exceeded: 50ms

1 total, 1 failed, 0 skipped, took 0.050 seconds

Last edited Nov 1, 2012 at 2:44 AM by BradWilson, version 10