SuperAPI AI Directory

dotnet-testing-advanced-tunit-fundamentals

Testing & quality

View repository

Updated 10-15 23:45

About this skill

TUnit New-Generation Testing Framework Getting Started Basics

TUnit Framework Core Features

1. Source Generator-Driven Test Discovery

The biggest difference between TUnit and traditional testing frameworks is that it uses a Source Generator atcompile timeto complete test discovery, avoiding reflection costs, fully supporting Native AOT, and providing faster startup time.

// TUnit 在編譯時期就透過 Source Generator 產生測試註冊程式碼
public class ModernTests
{
    [Test] // 編譯時期就被處理和最佳化
    public async Task TestMethod()
    {
        await Assert.That(true).IsTrue();
    }
}

2. AOT (Ahead-of-Time) Compilation Support

傳統 JIT:C# 原始碼 → IL 中間碼 → 執行時期 JIT 編譯 → 機器碼 → 執行
AOT:    C# 原始碼 → 編譯時期直接產生 → 機器碼 → 直接執行

AOT advantages: ultra-fast startup time, smaller memory footprint, predictable performance, and better suitability for containerized deployment. Large projects can achieve 10-30x startup time improvement.

3. Microsoft.Testing.Platform Adoption

TUnit is built on Microsoft's latest Microsoft.Testing.Platform, rather than the traditional VSTest platform.

Important note: TUnit projectsdo not needandshould notinstall the Microsoft.NET.Test.Sdk package.

4. Parallel Execution by Default

TUnit enables parallel execution by default; when needed, you can use [NotInParallel("GroupName")] to control specific test groups to run sequentially.

TUnit Project Creation

Supports manual creation (console template + TUnit package) or using the TUnit Template (dotnet new tunit, recommended). The project needs to configure the csproj (TUnit package, IsTestProject) and GlobalUsings.cs. All test methodsmust be asynchronous(async Task)。

For complete project creation steps and csproj examples, see references/project-setup.md

Test Attributes and Parameterization

Basic Test [Test]

TUnit uniformly uses the [Test] attribute, unlike xUnit which distinguishes between [Fact] and [Theory]:

[Test]
public async Task Add_輸入1和2_應回傳3()
{
    var calculator = new Calculator();
    var result = calculator.Add(1, 2);
    await Assert.That(result).IsEqualTo(3);
}

Parameterized Test [Arguments]

[Test]
[Arguments(1, 2, 3)]
[Arguments(-1, 1, 0)]
[Arguments(0, 0, 0)]
public async Task Add_多組輸入_應回傳正確結果(int a, int b, int expected)
{
    var calculator = new Calculator();
    var result = calculator.Add(a, b);
    await Assert.That(result).IsEqualTo(expected);
}

TUnit.Assertions Assertion System

TUnit adopts a fluent assertion design, and all assertions are asynchronous. It supports equality, boolean, numeric comparison, string, collection, exception, and many other assertions, and can combine conditions via And / Or .

await Assert.That(actual).IsEqualTo(expected);
await Assert.That(email).Contains("@").And.EndsWith(".com");
await Assert.That(() => action()).Throws<InvalidOperationException>();

For complete assertion types and examples, see references/tunit-assertions-detail.md

Test Lifecycle Management

TUnit supports the constructor / Dispose pattern, as well as [Before(Test)]、[Before(Class)]、[After(Test)]、[After(Class)] and other attributes.

執行順序:Before(Class) → 建構式 → Before(Test) → 測試方法 → After(Test) → Dispose → After(Class)

For complete lifecycle examples and attribute comparison tables, see references/lifecycle-management.md

Parallel Execution Control and xUnit Migration

TUnit runs all tests in parallel by default; use [NotInParallel] to control specific groups to run sequentially. It provides a complete xUnit → TUnit syntax comparison table, migration examples, CLI execution commands, and IDE integration settings.

For complete concurrency control, syntax comparison, and migration examples, see references/xunit-migration.md

Performance Comparison

Scenario xUnit TUnit TUnit AOT Performance Improvement
Simple Test Execution 1,400ms 1,000ms 60ms 23x (AOT)
Asynchronous Tests 1,400ms 930ms 26ms 54x (AOT)
Parallel Tests 1,425ms 999ms 54ms 26x (AOT)

Common Issues and Solutions

  1. Package Compatibility — Remove Microsoft.NET.Test.Sdk, TUnit uses the new testing platform
  2. IDE Integration Issues — Confirm the IDE version supports Microsoft.Testing.Platform and enable the relevant preview features
  3. Forgotten async assertions — All assertions require await, and test methods must be async Task

Applicable Scenario Assessment

Suitable for using TUnit

  1. Brand-new projects: No legacy baggage
  2. High performance requirements: Large test suites (1000+ tests)
  3. Modern tech stack: Using .NET 8+, planning to adopt AOT
  4. Heavy CI/CD usage: Test execution time directly affects deployment frequency
  5. Containerized deployment: Fast startup time is important

Not recommended for now

  1. Legacy projects: Already have a large number of xUnit tests
  2. Conservative teams: Need stability over innovation
  3. Complex test ecosystem: Heavy use of xUnit-specific packages
  4. Older .NET: Still on .NET 6/7

Output Format

  • Generate TUnit test classes (including [Test] and [Arguments] attributes)
  • Generate .csproj configuration (TUnit package references)
  • Provide GlobalUsings.cs configuration
  • Include a migration code comparison from xUnit to TUnit

Reference Resources

Original Article

The content of this skill is distilled from the article series "Old-School Software Engineer's Testing Practice - 30-Day Challenge":

Official Resources

Microsoft Official Documentation

Related Skills

  • dotnet-testing-advanced-tunit-advanced - TUnit Advanced Features
  • dotnet-testing-advanced-xunit-upgrade-guide - xUnit Upgrade Guide
  • dotnet-testing-xunit-project-setup - xUnit Project Setup (for comparison)