---
title: "Adding test description for data-driven tests in xUnit"
description: "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."
updated: 2025-06-30
tags: ["C#", "xUnit", "Testing"]
canonical: "https://steven-giesel.com/blogPost/80a53df4-a867-4202-916c-08e980f02505/adding-test-description-for-datadriven-tests-in-xunit"
---

# Adding test description for data-driven tests in xUnit

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:

```csharp
[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](https://linkdotnetblog.azureedge.net/blog/20250630_XunitDescription/old.webp)

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 `record`this 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:

```csharp
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:
```csharp
public static TheoryData<LimitDesignerFilters> InvalidFilters =>
[
    new("Workpiece is null", null, [1], [1], [1]),
    new("Param1 is null",  Guid.NewGuid(), null, [1], [1]),
];
```

![new](https://linkdotnetblog.azureedge.net/blog/20250630_XunitDescription/new.webp)

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