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
94%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
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.
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.Sdkusing 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.
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) { ... }[Fact(Skip = "Requires staging DB")]
public void SkippedTest() { }
[Fact]
[Trait("Category", "Integration")]
public void IntegrationTest() { }
// Filter: dotnet test --filter "Category=Integration"For per-test, class (IClassFixture), and collection
(ICollectionFixture) shared setup, plus assembly-level parallel
config, see
references/fixtures-and-parallelism.md.
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);
}
}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.
- 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 }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-pattern | Why it fails | Fix |
|---|---|---|
Console.WriteLine instead of ITestOutputHelper | Output suppressed | Use ITestOutputHelper (Step 5) |
Use [Theory] without data attribute | Test never runs | Always include [InlineData] etc. |
Shared mutable state in IClassFixture | Test order dependence | Per-test fresh state OR [Collection] synchronization |
| Skip parallel tuning at scale | Slow CI | Per-assembly + per-collection config (see references/fixtures-and-parallelism.md) |
--filter.nunit-tests,
mstest-tests,
fluentassertions - sister toolstest-code-conventions