Test parameterization in xUnit.net similar to NUnit

UserControl picture UserControl · Feb 2, 2012 · Viewed 48.4k times · Source

Are there any means in xUnit.net framework similar to the following features of NUnit?

[Test, TestCaseSource("CurrencySamples")]
public void Format_Currency(decimal value, string expected){}

static object[][] CurrencySamples = new object[][]
{
    new object[]{ 0m, "0,00"},
    new object[]{ 0.0004m, "0,00"},
    new object[]{ 5m, "5,00"},
    new object[]{ 5.1m, "5,10"},
    new object[]{ 5.12m, "5,12"},
    new object[]{ 5.1234m, "5,12"},
    new object[]{ 5.1250m, "5,13"}, // round
    new object[]{ 5.1299m, "5,13"}, // round
}

This will generate 8 separate tests in NUnit GUI

[TestCase((string)null, Result = "1")]
[TestCase("", Result = "1")]
[TestCase(" ", Result = "1")]
[TestCase("1", Result = "2")]
[TestCase(" 1 ", Result = "2")]
public string IncrementDocNumber(string lastNum) { return "some"; }

This will generate 5 separate tests and automatically compare the results (Assert.Equal()).

[Test]
public void StateTest(
    [Values(1, 10)]
    int input,
    [Values(State.Initial, State.Rejected, State.Stopped)]
    DocumentType docType
){}

This will generate 6 combinatorial tests. Priceless.

Few years ago I tried xUnit and loved it but it lacked these features. Can't live without them. Has something changed?

Answer

Enrico Campidoglio picture Enrico Campidoglio · Feb 2, 2012

xUnit offers a way to run parameterized tests through something called data theories. The concept is equivalent to the one found in NUnit but the functionality you get out of the box is not as complete.

Here's an example:

[Theory]
[InlineData("Foo")]
[InlineData(9)]
[InlineData(true)]
public void Should_be_assigned_different_values(object value)
{
    Assert.NotNull(value);
}

In this example xUnit will run the Should_format_the_currency_value_correctly test once for every InlineDataAttribute each time passing the specified value as argument.

Data theories are an extensibility point that you can use to create new ways to run your parameterized tests. The way this is done is by creating new attributes that inspect and optionally act upon the arguments and return value of the test methods.

You can find a good practical example of how xUnit's data theories can be extended in AutoFixture's AutoData and InlineAutoData theories.