Here is a summary of some of our favorite new features in v3:

Enhanced Test Context

The new TestContext class offers real-time information about the test pipeline, supports test cancellation, allows sending diagnostic messages, and lets you add attachments to test results. These features simplify the management of complex test scenarios and bring xUnit in line with the functionality of other popular test frameworks, such as NUnit and MSTest.

[Fact] public async Task MyAsyncTest() { // This is how you use TestContext.Current.CancellationToken, // which allows you to know when the test runner is expecting cancellation. await Task.Delay(100, TestContext.Current.CancellationToken); // This is how you can an add an attahment to the test results. if (TestContext.Current.TestState?.Result == TestResult.Failed) { TestContext.Current.AddAttachment("screenshot", Encoding.UTF8.GetBytes("Fake Screenshot"), "image/png"); } }

Improved Theory Data Handling

Theory data handling now supports asynchronous data retrieval and metadata decoration. You can mark tests as explicitly skipped, set custom display names, and more.

[Theory] [MemberData(nameof(GetDataAsync), DisableDiscoveryEnumeration = true)] public async Task MyDataDrivenTest(int id, string name) { Assert.NotEmpty(name); } public static async Task<IEnumerable<object[]>> GetDataAsync() { await Task.Delay(100); // Simulate asynchronous data fetching return new List<object[]> { new object[] { 1, "Alice" } }; }

Test Pipeline Startup

xUnit v3 allows you to run setup and cleanup code at the start and end of the test pipeline. This ensures proper initialization before test discovery and execution, and cleanup after all tests are done.

In this example, StartAsync runs at the beginning, and StopAsync runs after all tests finish:

public class MyTestPipelineStartup : ITestPipelineStartup { public async Task StartAsync() { Console.WriteLine("Test pipeline starting..."); await Task.CompletedTask; } public async Task StopAsync() { Console.WriteLine("Test pipeline stopping..."); await Task.CompletedTask; } }

Apply it at the assembly level:

[assembly: TestPipelineStartup(typeof(MyTestPipelineStartup))]

Dynamic Test Skippability
Tests can now be dynamically skipped at runtime based on conditions like the operating system or environment. This adds flexibility, especially in cross-platform environments.

[Fact] public void TestOSCompatibility() { Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Requires Windows."); }

Explicit Test Support

Explicit tests in xUnit v3 are only run when specifically requested. This is ideal for tests that need special conditions or setup before being executed.

[Fact(Explicit = true)] public void IntegrationTest() { // This test will only run when explicitly selected. }

Wrapping Up

xUnit v3 is shaping up to be a great update. These new features simplify test management and give developers better control over how tests are run and reported.

New features are continually being added to xUnit v3. For the latest updates, visit the xUnit v3 guide.