xUnit.net
NUnit
test parameterization
unit testing
C# testing

Test parameterization in xUnit.net similar to NUnit

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

xUnit.net supports parameterized tests, but it uses a different vocabulary than NUnit. Where NUnit developers often think in terms of [TestCase] and [TestCaseSource], xUnit.net uses [Theory] together with data sources such as [InlineData], [MemberData], and [ClassData].

Use [Theory] and [InlineData] for Simple Cases

The closest xUnit equivalent to a small NUnit parameterized test is a theory with inline values.

csharp
1using Xunit;
2
3public class MathTests
4{
5    [Theory]
6    [InlineData(1, 2, 3)]
7    [InlineData(2, 3, 5)]
8    [InlineData(10, 5, 15)]
9    public void Add_ReturnsExpectedValue(int a, int b, int expected)
10    {
11        Assert.Equal(expected, a + b);
12    }
13}

This covers the same general use case as several NUnit [TestCase] attributes.

The important difference is conceptual:

  • '[Fact] means one test with no parameters'
  • '[Theory] means one test shape executed with supplied data'

Use [MemberData] for Richer Inputs

When the test cases are too large or complex for inline attributes, move them into a member that returns data.

csharp
1using System.Collections.Generic;
2using Xunit;
3
4public class ParsingTests
5{
6    public static IEnumerable<object[]> ParseCases =>
7        new List<object[]>
8        {
9            new object[] { "42", 42 },
10            new object[] { "007", 7 },
11            new object[] { "-3", -3 }
12        };
13
14    [Theory]
15    [MemberData(nameof(ParseCases))]
16    public void IntParsing_Works(string input, int expected)
17    {
18        Assert.Equal(expected, int.Parse(input));
19    }
20}

This is closer to NUnit’s source-driven parameterization and keeps the test method readable when case data grows.

Use [ClassData] for Reusable Test Data Objects

If several tests share the same dataset or you want a dedicated type to generate the cases, use ClassData.

csharp
1using System.Collections;
2using System.Collections.Generic;
3using Xunit;
4
5public class NumberCases : IEnumerable<object[]>
6{
7    public IEnumerator<object[]> GetEnumerator()
8    {
9        yield return new object[] { 2, true };
10        yield return new object[] { 3, false };
11        yield return new object[] { 4, true };
12    }
13
14    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
15}
16
17public class EvenTests
18{
19    [Theory]
20    [ClassData(typeof(NumberCases))]
21    public void IsEven_Works(int value, bool expected)
22    {
23        Assert.Equal(expected, value % 2 == 0);
24    }
25}

This is helpful when test data has its own structure or should be reused across multiple test classes.

Compare the xUnit and NUnit Mindsets

NUnit often feels attribute-heavy and flexible in a very direct way. xUnit.net pushes you more toward explicit data sources and code-based organization.

A practical mapping looks like:

  • NUnit [Test] -> xUnit [Fact]
  • NUnit [TestCase] -> xUnit [Theory] plus [InlineData]
  • NUnit [TestCaseSource] -> xUnit [MemberData] or [ClassData]

That means the feature exists, but the style is slightly different. xUnit wants the data source to be visible and strongly tied to the test method’s execution model.

Keep Parameterized Tests Focused

Parameterized tests are most useful when:

  • the same assertion logic applies to many cases
  • each input set is easy to understand
  • a failing case is still readable in test output

They are less useful when one theory tries to cover too many unrelated behaviors. In those situations, separate test methods are often clearer than one huge parameterized test.

Common Pitfalls

  • Using [Fact] when parameters are required causes confusion because xUnit expects [Theory] for data-driven tests.
  • Packing too much logic into one theory makes failures harder to interpret than a few focused tests would be.
  • Choosing [InlineData] for large or complex inputs makes the test hard to read.
  • Forgetting that [MemberData] and [ClassData] must match the method signature leads to runtime data-binding errors.
  • Translating NUnit patterns mechanically without adopting xUnit’s theory-oriented style often produces awkward tests.

Summary

  • xUnit.net supports parameterized testing through [Theory].
  • Use [InlineData] for small simple cases.
  • Use [MemberData] or [ClassData] when test data is larger or reusable.
  • The feature set is comparable to NUnit, but the API style is different.
  • Good parameterized tests keep one assertion shape and vary only the input data cleanly.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.