Data Driven Tests
A data driven test runs the same test code several times, with different input data each time. Instead of copying a test to try another value, you write the test once and give NUnit the list of values. Each set of values shows up as its own test in the test explorer, so you can see exactly which case failed.
NUnit calls these parameterized tests: the test method takes parameters, and the data is supplied from outside.
Inline data with [TestCase]
Use [TestCase] when you have a handful of cases that are easy to write out. Each
attribute is one test case, and its arguments are passed to the method parameters in order.
public class AddTests
{
[TestCase(1, 2, 3)]
[TestCase(2, 3, 5)]
[TestCase(-1, 1, 0)]
public void Add_ReturnsSum(int a, int b, int expected)
{
var result = new Calculator().Add(a, b);
Assert.That(result, Is.EqualTo(expected));
}
}
If the test simply computes a value, you can let the method return it and put the expected value in the attribute
with ExpectedResult:
public class AddTestsWithExpectedResult
{
[TestCase(1, 2, ExpectedResult = 3)]
[TestCase(2, 3, ExpectedResult = 5)]
public int Add_ReturnsSum(int a, int b)
{
return new Calculator().Add(a, b);
}
}
Data from code with [TestCaseSource]
Use [TestCaseSource] when the data is larger, needs code to build, or comes from
somewhere else, such as a file. Point the attribute at a static method, property or field that returns the cases.
public class AddTestsFromSource
{
private static IEnumerable<TestCaseData> AddCases()
{
yield return new TestCaseData(1, 2, 3).SetName("Small numbers");
yield return new TestCaseData(1000, 2000, 3000).SetName("Large numbers");
yield return new TestCaseData(-5, 5, 0).SetDescription("Opposites cancel out");
}
[TestCaseSource(nameof(AddCases))]
public void Add_ReturnsSum(int a, int b, int expected)
{
Assert.That(new Calculator().Add(a, b), Is.EqualTo(expected));
}
}
Returning TestCaseData objects is optional, but it lets you give each case a readable name, a
description, categories and more. To name many test cases with one pattern, see
Template Based Test Naming.
Data for a single parameter with [ValueSource]
Use [ValueSource] when you want to supply the values for one parameter from a
reusable list.
public class MultiplyByOneTests
{
private static readonly int[] Numbers = [0, 1, 42, -7];
[Test]
public void Multiply_ByOne_ReturnsSameNumber([ValueSource(nameof(Numbers))] int number)
{
Assert.That(new Calculator().Multiply(number, 1), Is.EqualTo(number));
}
}
Running a whole class with different data
You can also pass data to the test class itself. Every test in the class then runs once for each set of arguments given
with [TestFixture].
[TestFixture(2)]
[TestFixture(10)]
public class MultiplierTests(int multiplier)
{
[Test]
public void Multiply_ByZero_ReturnsZero()
{
Assert.That(new Calculator().Multiply(multiplier, 0), Is.Zero);
}
[Test]
public void Multiply_ByOne_ReturnsMultiplier()
{
Assert.That(new Calculator().Multiply(multiplier, 1), Is.EqualTo(multiplier));
}
}
For data built in code, use [TestFixtureSource] and
TestFixtureData.
Next steps
- Automating tests lets NUnit generate combinations of values for you.
- Parameterized tests describes all the details of how parameterized tests work.