Overview
By combining the [Theory] and [InlineData] attributes in xUnit.net, you can execute a single test method multiple times with different input patterns. This is called “Parameterized Testing” or “Data-Driven Testing.” It is an efficient way to verify various patterns, such as boundary values and error cases.
Specifications (Input/Output)
- Attributes:
[Theory]: Declares a parameterized test (used instead of the standard[Fact]).[InlineData(val1, val2, ...)]: Defines the specific values to be passed to the test method’s arguments. You can write multiple lines of this attribute.
- Behavior: The test is executed repeatedly, once for each
InlineDataentry defined.
Basic Usage
[Theory]
[InlineData(1, 2, 3)] // a=1, b=2, expected=3
[InlineData(5, 5, 10)] // a=5, b=5, expected=10
public void SumTest(int a, int b, int expected)
{
Assert.Equal(expected, a + b);
}
Full Code
This example implements a pattern where the expected value is received as the first argument to verify if the sum of two numbers is correct.
using System;
using Xunit;
namespace ParameterizedTests
{
public class CalculationTests
{
/// <summary>
/// [Theory] declares a parameterized test.
/// [InlineData] specifies specific test cases (expected, x, y).
/// </summary>
[Theory]
[InlineData(20, 0, 20)] // 0 + 20 = 20
[InlineData(7, 2, 5)] // 2 + 5 = 7
[InlineData(10, 16, -6)] // 16 + (-6) = 10
public void Add_MultipleInputs_ReturnsCorrectSum(int expected, int x, int y)
{
// Arrange
var obj = new MySampleClass();
// Act
var val = obj.Add(x, y);
// Assert
Assert.Equal(expected, val);
}
}
/// <summary>
/// Class to be tested
/// </summary>
public class MySampleClass
{
public int Add(int x, int y)
{
return x + y;
}
}
}
Customization Points
- Number and Type of Arguments: The number and type of arguments in
InlineDatamust match the parameters defined in the test method. If they do not match, an error will occur during test execution or compilation. - Detailed Test Names: In the test runner, each set of parameters is displayed as a separate test result (e.g.,
Add_MultipleInputs_ReturnsCorrectSum(expected: 20, x: 0, y: 20)).
Points of Caution
- Do Not Use with Fact: When using
[Theory], do not include the[Fact]attribute. Using both will cause an error. - Complex Data:
InlineDataonly supports constant values (numbers, strings, null, etc.). If you need to pass complex data like arrays, objects, or data from a file, use the[MemberData]or[ClassData]attributes instead. - Argument Order: Values in
InlineDataare mapped to the test method’s arguments from left to right. Ensure the order is correct.
Application
Mixing Multiple Types
You can combine arguments of different types, such as strings and booleans.
[Theory]
[InlineData("apple", 5, true)]
[InlineData("banana", 10, false)]
public void StringLengthTest(string text, int length, bool isShort)
{
// ... Verification logic
}
Summary
Using [InlineData] eliminates the need to copy and paste similar test code repeatedly, which dramatically improves the maintainability of your test suite. You should actively use this feature for boundary value testing (0, negative values, maximum values, etc.) and to cover various normal operation patterns.
