The Principal Dev โ€“ Masterclass for Tech Leads

The Principal Dev โ€“ Masterclass for Tech Leads28-29 May

Join

TUnit

TUnit

A modern .NET testing framework. Tests are source-generated at compile time, run in parallel by default, and support Native AOT โ€” all built on Microsoft.Testing.Platform.

thomhurst%2FTUnit | Trendshift

Codacy Badge GitHub Repo stars GitHub Issues or Pull Requests GitHub Sponsors nuget NuGet Downloads GitHub Workflow Status (with event) GitHub last commit (branch) License

Features

Getting Started

dotnet new install TUnit.Templates
dotnet new TUnit -n "MyTestProject"
cd MyTestProject
dotnet run

Manual Installation

dotnet add package TUnit

Getting Started Guide ยท Migration Guides

Examples

Basic test with assertions

[Test]
public async Task Parsing_A_Valid_Date_Succeeds()
{
    var date = DateTime.Parse("2025-01-01");

    await Assert.That(date.Year).IsEqualTo(2025);
    await Assert.That(date.Month).IsEqualTo(1);
}

Data-driven tests

[Test]
[Arguments("user1@test.com", "ValidPassword123")]
[Arguments("user2@test.com", "AnotherPassword456")]
[Arguments("admin@test.com", "AdminPass789")]
public async Task User_Login_Should_Succeed(string email, string password)
{
    var result = await authService.LoginAsync(email, password);
    await Assert.That(result.IsSuccess).IsTrue();
}

// Matrix โ€” generates a test for every combination (9 total here)
[Test]
[MatrixDataSource]
public async Task Database_Operations_Work(
    [Matrix("Create", "Update", "Delete")] string operation,
    [Matrix("User", "Product", "Order")] string entity)
{
    await Assert.That(await ExecuteOperation(operation, entity))
        .IsTrue();
}

Hooks, dependencies, and retry

[Before(Class)]
public static async Task SetupDatabase(ClassHookContext context)
{
    await DatabaseHelper.InitializeAsync();
}

[Test]
[MethodDataSource(nameof(GetTestUsers))]
public async Task Register_User(string username, string password) { ... }

[Test, DependsOn(nameof(Register_User))]
[Retry(3)]
public async Task Login_With_Registered_User(string username, string password)
{
    // Guaranteed to run after Register_User passes
}

Custom attributes

Extend built-in base classes to create your own skip conditions, retry logic, and more:

public class WindowsOnlyAttribute : SkipAttribute
{
    public WindowsOnlyAttribute() : base("Windows only") { }

    public override Task<bool> ShouldSkip(TestContext testContext)
        => Task.FromResult(!OperatingSystem.IsWindows());
}

[Test, WindowsOnly]
public async Task Windows_Specific_Feature() { ... }

See the documentation for more examples, including custom retry logic and data sources.

IDE Support

IDE Notes
Visual Studio 2022 (17.13+) Works out of the box
Visual Studio 2022 (earlier) Enable "Use testing platform server mode" in Tools > Manage Preview Features
JetBrains Rider Enable "Testing Platform support" in Settings > Build, Execution, Deployment > Unit Testing > Testing Platform
VS Code Install C# Dev Kit and enable "Use Testing Platform Protocol"
CLI Works with dotnet test, dotnet run, and direct execution

Packages

Package Purpose
TUnit Start here โ€” the full framework (Core + Engine + Assertions)
TUnit.Core Shared test library components without an execution engine
TUnit.Engine Execution engine for test projects
TUnit.Assertions Standalone assertions โ€” works with other test frameworks too
TUnit.Playwright Playwright integration with automatic browser lifecycle management

Migrating from xUnit, NUnit, or MSTest?

The syntax will feel familiar. For example, xUnit's [Fact] becomes [Test], and [Theory] + [InlineData] becomes [Test] + [Arguments]. See the migration guides for full details: xUnit ยท NUnit ยท MSTest.

Community

Join libs.tech

...and unlock some superpowers

GitHub

We won't share your data with anyone else.