CtrlK
BlogDocsLog inGet started
Tessl Logo

testland/xunit-tests

Configures and runs xUnit.net (xUnit v2 + v3) - current de facto .NET test framework with `[Fact]` for single tests + `[Theory]` + `[InlineData]`/`[ClassData]`/`[MemberData]` for parametrized; collection fixtures (`[Collection]`) + class fixtures (`IClassFixture`) for shared setup; output via `ITestOutputHelper`; parallel test config via assembly attribute. Use when working with .NET (C# / F# / VB.NET) on the modern test stack.

75

Quality

94%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

Overview
Quality
Evals
Security
Files
name:
xunit-tests
description:
Configures and runs xUnit.net (xUnit v2 + v3) - current de facto .NET test framework with `[Fact]` for single tests + `[Theory]` + `[InlineData]`/`[ClassData]`/`[MemberData]` for parametrized; collection fixtures (`[Collection]`) + class fixtures (`IClassFixture`) for shared setup; output via `ITestOutputHelper`; parallel test config via assembly attribute. Use when working with .NET (C# / F# / VB.NET) on the modern test stack.

xunit-tests

Overview

Per xunit.net:

xUnit.net is the current .NET test standard (used by .NET Foundation projects + Microsoft's own .NET runtime). v3 released 2024; v2 still widely used in production.

Step 1 - Install

dotnet new xunit -n MyProjectTests
# Or in existing project:
dotnet add package xunit
dotnet add package xunit.runner.visualstudio
dotnet add package Microsoft.NET.Test.Sdk

Step 2 - First test

using Xunit;

public class CalculatorTests
{
    [Fact]
    public void Adds_TwoNumbers()
    {
        Assert.Equal(3, Calculator.Add(1, 2));
    }
}

Run: dotnet test. Verify: assert the run reports Passed! with the expected test count before proceeding; if it exits non-zero or discovers 0 tests, confirm the class is public, the method carries [Fact], and all three packages (xunit, xunit.runner.visualstudio, Microsoft.NET.Test.Sdk) are installed, then re-run.

Step 3 - Parametrized tests

Per xn-docs:

[Theory]
[InlineData(1, 2, 3)]
[InlineData(0, 0, 0)]
[InlineData(-1, 1, 0)]
public void Adds_VariousInputs(int a, int b, int expected)
{
    Assert.Equal(expected, Calculator.Add(a, b));
}

// Class-based data source
public class AddTestData : IEnumerable<object[]>
{
    public IEnumerator<object[]> GetEnumerator()
    {
        yield return new object[] { 1, 2, 3 };
        yield return new object[] { 0, 0, 0 };
    }
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

[Theory]
[ClassData(typeof(AddTestData))]
public void Adds_FromClassData(int a, int b, int expected) { ... }

// Method-based
public static IEnumerable<object[]> AddCases =>
    new List<object[]> {
        new object[] { 1, 2, 3 },
        new object[] { 0, 0, 0 },
    };

[Theory]
[MemberData(nameof(AddCases))]
public void Adds_FromMemberData(int a, int b, int expected) { ... }

Step 4 - Skip + traits

[Fact(Skip = "Requires staging DB")]
public void SkippedTest() { }

[Fact]
[Trait("Category", "Integration")]
public void IntegrationTest() { }

// Filter:  dotnet test --filter "Category=Integration"

Fixtures + parallelism

For per-test, class (IClassFixture), and collection (ICollectionFixture) shared setup, plus assembly-level parallel config, see references/fixtures-and-parallelism.md.

Step 5 - Output (ITestOutputHelper)

xUnit suppresses Console.WriteLine in tests. Use ITestOutputHelper:

public class TestsWithOutput {
    private readonly ITestOutputHelper _output;
    public TestsWithOutput(ITestOutputHelper output) { _output = output; }

    [Fact]
    public void LogsContext() {
        _output.WriteLine("Test running at {0}", DateTime.UtcNow);
    }
}

Step 6 - Pair with FluentAssertions

result.Should().Be(42);
list.Should().HaveCount(3).And.Contain("alice");
result.Should().BeOfType<Success>().Which.Value.Should().Be(42);

See fluentassertions. Note: FluentAssertions changed license in 2024 (paid commercial; free for OSS); v6 is the last fully-free version.

Step 7 - CI integration

- run: dotnet test --logger "trx;LogFileName=test-results.trx" \
    --collect:"XPlat Code Coverage" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=opencover
- uses: codecov/codecov-action@v4
  with: { files: ./coverage/coverage.opencover.xml }

Worked example

A service team writes xUnit coverage for a UserService backed by a database. They scaffold with dotnet new xunit (Step 1), cover pure logic like Calculator.Add with the [Theory] of Step 3, and park a staging-only case with the skip of Step 4. The DB-backed classes share one DatabaseFixture via a [Collection("DbCollection")] (see references/fixtures-and-parallelism.md) so they run sequentially against the shared connection while pure-logic tests parallelize. Diagnostics go through ITestOutputHelper (Step 5), and CI runs the coverage command of Step 7. Result: fast parallel unit coverage plus serialized DB-backed tests sharing one fixture.

Anti-patterns

Anti-patternWhy it failsFix
Console.WriteLine instead of ITestOutputHelperOutput suppressedUse ITestOutputHelper (Step 5)
Use [Theory] without data attributeTest never runsAlways include [InlineData] etc.
Shared mutable state in IClassFixtureTest order dependencePer-test fresh state OR [Collection] synchronization
Skip parallel tuning at scaleSlow CIPer-assembly + per-collection config (see references/fixtures-and-parallelism.md)

Limitations

  • xUnit's "constructor as setup, IDisposable as teardown" is unintuitive vs JUnit's annotations.
  • Test discovery is slow on large solutions; use --filter.
  • v2 vs v3 API has minor breaking changes; pin version per project.

References

  • xn-docs - xUnit.net documentation
  • xunit.net - landing
  • learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-with-dotnet-test - dotnet test
  • references/fixtures-and-parallelism.md - fixtures + parallel execution
  • nunit-tests, mstest-tests, fluentassertions - sister tools
  • test-code-conventions
Workspace
testland
Visibility
Public
Created
Last updated
Publish Source
GitHub
Badge
testland/xunit-tests badge