Data Driven Test

A single test method that can be executed multiple times, each time using a discreet set of test data, with each execution representing an individual case.

Elements of Data Driven Test

Elements of Data Driven Test

DataAttribute for Theory

xUnit.net itself supplies various attributes that derive from DataAttribute:

InlineData Attribute

[Theory]
[InlineData(1, 2, 3)]
[InlineData(int.MinValue, -1, int.MaxValue)]
public void CanAddTheory(int valueOne, int valueTwo, int expected)
{
    var calculator = new Calculator();

    var result = calculator.Add(valueOne, valueTwo);

    Assert.Equal(expected, result);
}

MemberData Attribute

Requirements:

Static Method

public class CalculatorTests
{

    public static IEnumerable<object[]> GetNumbers()
    {
        yield new object[] { 1, 2, 3 },
        yield new object[] { int.MinValue, -1, int.MaxValue },
    }

    [Theory]
    [MemberData(nameof(GetNumbers))]
    public void CanAddTheoryMemberDataByMethod(int valueOne, int valueTwo, int expected)
    {
        // Assert here
    }
}

Static Property

public class CalculatorTests
{
    public static IEnumerable<object[]> Data =>
        new List<object[]>
        {
            new object[] { 1, 2, 3 },
            new object[] { int.MinValue, -1, int.MaxValue },
        };

    [Theory]
    [MemberData(nameof(Data))]
    public void CanAddTheoryMemberDataByProperty(int valueOne, int valueTwo, int expected)
    {
        // Assert here
    }
}

MemberData from External class

ExtDataSource.cs

public class ExtDataSource
{
    public static IEnumerable<object[]> GetNumbers()
    {
        // in memory data
        // data from file (csv/json/excel)
    }
}

CalculatorTests.cs

public class CalculatorTests
{

    [Theory]
    [MemberData(nameof(ExtDataSource.GetNumbers), MemberType = typeof(ExtDataSource))]
    public void CanAddTheoryMemberDataByMethod(int valueOne, int valueTwo, int expected)
    {
        // Assert here
    }
}

ClassData Attribute

public class CalculatorTestData : IEnumerable<object[]>
{
    public IEnumerator<object[]> GetEnumerator()
    {
        yield return new object[] { 1, 2, 3 };
        yield return new object[] { -4, -6, -10 };
        yield return new object[] { -2, 2, 0 };
        yield return new object[] { int.MinValue, -1, int.MaxValue };
    }

    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
    //IEnumerator IEnumerable.GetEnumerator() => new List<object[]>(File.ReadAllLines("foo.csv")).GetEnumerator();
}

Using CalculatorTestData

[Theory]
[ClassData(typeof(CalculatorTestData))]
public void CanAddTheoryClassData(int value1, int value2, int expected)
{
    var calculator = new Calculator();

    var result = calculator.Add(value1, value2);

    Assert.Equal(expected, result);
}