Adding test description for data-driven tests in xUnit

6/30/2025
3 minute read

Often times, you find yourself in writing data-driven tests in xUnit (like Theory tests) and you want to add a description to each test case. Let's explore how to do that.

The problem

Let's imagine you have a test as such:

[Theory]
[MemberData(nameof(InvalidFilters))]
public async Task ShouldNotAllowInvalidInvariants(LimitDesignerFilters filters)
...

    public record LimitDesignerFilters(
        string Description,
        Guid? WorkpieceNumber,
        IReadOnlyCollection<int>? DressingIds,
        IReadOnlyCollection<int>? DressingTools,
        IReadOnlyCollection<int>? LimitIds);

If we execute the test, then we get something like this in the test runner:

old

As we see it is really hard to understand what each test case is about, especially given that we have some collections and thanks to the recordthis will internally use the ToString() method to display the values. So - we can exactly use that to our advantage.

The solution - overriding ToString()

To make the test runner display a more meaningful description, we can override the ToString() method in our LimitDesignerFilters record. This way, we can format the output to be more readable and informative. So let's add a description field and override the ToString() method:

public record LimitDesignerFilters(
    string Description,
    Guid? WorkpieceNumber,
    IReadOnlyCollection<int>? DressingIds,
    IReadOnlyCollection<int>? DressingTools,
    IReadOnlyCollection<int>? LimitIds)
{
    public override string ToString() => Description;
}

So we can set the Description field to a meaningful value for each test case:

public static TheoryData<LimitDesignerFilters> InvalidFilters =>
[
    new("Workpiece is null", null, [1], [1], [1]),
    new("Param1 is null",  Guid.NewGuid(), null, [1], [1]),
];

new

Still "filters" as the name of the passed in parameter is still there, but at least a better name.

An error has occurred. This application may no longer respond until reloaded. Reload x