Source: kevintsengtw/dotnet-testing-agent-skills (MIT). Ported into dotnet-agent-harness.
TUnit New Generation Testing Framework Introduction
Applicable Scenarios
This skill covers TUnit new-generation .NET testing framework introduction basics, from framework features to actual
project creation and test writing.
Core Topics
- TUnit framework features and design philosophy
- Source Generator driven test discovery
- AOT (Ahead-of-Time) compilation support
- Fluent async assertion system
- Project creation and package configuration
- Syntax differences compared to xUnit
TUnit Framework Core Features
1. Source Generator Driven Test Discovery
TUnit's biggest difference from traditional testing frameworks is using Source Generator to complete test discovery at
compile time:
Traditional Framework Approach (xUnit)
// xUnit discovers all methods through reflection at runtime
public class TraditionalTests
{
[Fact] // Only discovered at runtime
public void TestMethod() { }
}
```text
### TUnit's Innovative Approach
```csharp
// TUnit generates test registration code at compile time through Source Generator
public class ModernTests
{
[Test] // Processed and optimized at compile time
public async Task TestMethod()
{
await Assert.That(true).IsTrue();
}
}
```text
### Advantages
1. Avoid reflection cost: All test discovery completed at compile time
2. AOT compatible: Fully supports Native AOT compilation
3. Faster startup time: Especially in large test projects
### 2. AOT (Ahead-of-Time) Compilation Support
### JIT vs AOT Compilation Flow
```text
Traditional JIT: C# source → IL bytecode → JIT compile at runtime → machine code → execute
AOT: C# source → directly generate at compile time → machine code → execute directly
```text
### AOT Compilation Advantages
- Ultra-fast startup time (no waiting for JIT compilation)
- Smaller memory footprint
- Predictable performance
- More suitable for containerized deployment
### Enable AOT Support
```xml
<PropertyGroup>
<PublishAot>true</PublishAot>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
```text
### Actual Performance Differences
```text
Traditional JIT compilation test startup time: ~1-2 seconds
TUnit AOT compilation test startup time: ~50-100 milliseconds
(Large projects can achieve 10-30x startup time improvement)
```text
### 3. Microsoft.Testing.Platform Adoption
TUnit is built on Microsoft's latest Microsoft.Testing.Platform, not the traditional VSTest platform:
- Lighter test runner
- Better parallel control mechanism
- Native support for latest IDE integration
### Important Notes
TUnit projects **do not need** and **should not** install `Microsoft.NET.Test.Sdk` package.
### 4. Default Parallel Execution
TUnit sets parallel execution as default and provides fine-grained control:
```csharp
// Default all tests execute in parallel
[Test]
public async Task ParallelTest1() { }
[Test]
public async Task ParallelTest2() { }
// Can control parallel behavior when needed
[Test]
[NotInParallel("DatabaseTests")]
public async Task DatabaseTest() { }
```text
---
## TUnit Project Creation
### Method One: Manual Creation (Understanding Underlying Architecture)
```bash
# Create project directory
mkdir TUnitDemo
cd TUnitDemo
# Create solution
dotnet new sln -n MyApp
# Create main project
dotnet new classlib -n MyApp.Core -o src/MyApp.Core
# Create test project (use console template)
dotnet new console -n MyApp.Tests -o tests/MyApp.Tests
# Add to solution
dotnet sln add src/MyApp.Core/MyApp.Core.csproj
dotnet sln add tests/MyApp.Tests/MyApp.Tests.csproj
# Add project reference
dotnet add tests/MyApp.Tests/MyApp.Tests.csproj reference src/MyApp.Core/MyApp.Core.csproj
```text
### Method Two: Using TUnit Template (Recommended)
```bash
# Install TUnit project templates
dotnet new install TUnit.Templates
# Create test project using TUnit template
dotnet new tunit -n MyApp.Tests -o tests/MyApp.Tests
```text
### Test Project csproj Configuration
```xml
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<!-- TUnit core packages -->
<PackageReference Include="TUnit" Version="0.57.24" />
<!-- Code coverage support -->
<PackageReference Include="Microsoft.Testing.Extensions.CodeCoverage" Version="17.12.4" />
<!-- TRX report support -->
<PackageReference Include="Microsoft.Testing.Extensions.TrxReport" Version="1.4.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\MyApp.Core\MyApp.Core.csproj" />
</ItemGroup>
</Project>
```text
### GlobalUsings Configuration
```csharp
// GlobalUsings.cs
global using TUnit.Core;
global using TUnit.Assertions;
global using MyApp.Core;
```text
---
## Async Test Methods (Required)
TUnit **requires all test methods to be async**, this is a framework technical requirement:
```csharp
// ❌ Error: won't compile
[Test]
public void WrongTest()
{
Assert.That(1 + 1).IsEqualTo(2);
}
// ✅ Correct: use async Task
[Test]
public async Task CorrectTest()
{
await Assert.That(1 + 1).IsEqualTo(2);
}
```text
---
## Test Attributes and Parameterization
### Basic Test [Test]
TUnit uniformly uses `[Test]` attribute, unlike xUnit which distinguishes `[Fact]` and `[Theory]`:
```csharp
// TUnit: uniformly use [Test]
[Test]
public async Task Add_Input1And2_ShouldReturn3()
{
var calculator = new Calculator();
var result = calculator.Add(1, 2);
await Assert.That(result).IsEqualTo(3);
}
```text
### Parameterized Tests [Arguments]
```csharp
// TUnit: use [Arguments] (equivalent to xUnit's [InlineData])
[Test]
[Arguments(1, 2, 3)]
[Arguments(-1, 1, 0)]
[Arguments(0, 0, 0)]
[Arguments(100, -50, 50)]
public async Task Add_MultipleInputs_ShouldReturnCorrectResult(int a, int b, int expected)
{
var calculator = new Calculator();
var result = calculator.Add(a, b);
await Assert.That(result).IsEqualTo(expected);
}
```text
---
## TUnit.Assertions Assertion System
TUnit adopts fluent assertion design, all assertions are async. Supports equality, boolean, numeric comparison, string, collection, exception, and other assertions, and can combine conditions through `And` / `Or`.
```csharp
// Basic usage examples
await Assert.That(actual).IsEqualTo(expected);
await Assert.That(email).Contains("@").And.EndsWith(".com");
await Assert.That(() => action()).Throws<InvalidOperationException>();
```text
> 📖 Complete assertion types and examples please refer to [TUnit Assertion System Detailed Description](references/tunit-assertions-detail.md)
---
## Test Lifecycle Management
TUnit supports constructor / `Dispose` pattern, and `[Before(Test)]`, `[Before(Class)]`, `[After(Test)]`, `[After(Class)]` and other attributes, providing more refined lifecycle control than xUnit.
```text
Execution order: Before(Class) → Constructor → Before(Test) → Test Method → After(Test) → Dispose → After(Class)
```text
> 📖 Complete lifecycle examples and attribute comparison table please refer to [Lifecycle Management Detailed Description](references/lifecycle-management.md)
---
## Parallel Execution Control
### NotInParallel Attribute
```csharp
// Default parallel execution
[Test]
public async Task ParallelTest1() { }
[Test]
public async Task ParallelTest2() { }
// Control specific tests not to run in parallel
[Test]
[NotInParallel("DatabaseTests")]
public async Task DatabaseTest1_NotInParallel()
{
// This test won't run in parallel with other "DatabaseTests" group
}
[Test]
[NotInParallel("DatabaseTests")]
public async Task DatabaseTest2_NotInParallel()
{
// Runs sequentially with DatabaseTest1
}
```text
---
## xUnit to TUnit Syntax Comparison
| Feature | xUnit | TUnit |
| ------- | ----- | ----- |
| **Basic Test** | `[Fact]` | `[Test]` |
| **Parameterized Test** | `[Theory]` + `[InlineData]` | `[Test]` + `[Arguments]` |
| **Basic Assertion** | `Assert.Equal(expected, actual)` | `await Assert.That(actual).IsEqualTo(expected)` |
| **Boolean Assertion** | `Assert.True(condition)` | `await Assert.That(condition).IsTrue()` |
| **Exception Test** | `Assert.Throws<T>(() => action())` | `await Assert.That(() => action()).Throws<T>()` |
| **Null Check** | `Assert.Null(value)` | `await Assert.That(value).IsNull()` |
| **String Check** | `Assert.Contains("text", fullString)` | `await Assert.That(fullString).Contains("text")` |
### Migration Example
### xUnit Original Code
```csharp
[Theory]
[InlineData("test@example.com", true)]
[InlineData("invalid", false)]
public void IsValidEmail_VariousInputs_ShouldReturnCorrectValidationResult(string email, bool expected)
{
var result = _validator.IsValidEmail(email);
Assert.Equal(expected, result);
}
```text
### TUnit Converted
```csharp
[Test]
[Arguments("test@example.com", true)]
[Arguments("invalid", false)]
public async Task IsValidEmail_VariousInputs_ShouldReturnCorrectValidationResult(string email, bool expected)
{
var result = _validator.IsValidEmail(email);
await Assert.That(result).IsEqualTo(expected);
}
```text
### Main Changes
1. `[Theory]` → `[Test]`
2. `[InlineData]` → `[Arguments]`
3. Method changed to `async Task`
4. All assertions prefixed with `await`
5. Fluent assertion syntax
---
## Execution and Debugging
### CLI Execution
```bash
# Build project
dotnet build
# Run all tests
dotnet test
# Verbose output
dotnet test --verbosity normal
# Generate coverage report
dotnet test --coverage
# Filter specific tests
dotnet test --filter "ClassName=CalculatorTests"
dotnet test --filter "TestName~Add"
```text
### AOT Compilation Execution
```bash
# Publish as AOT compiled version
dotnet publish -c Release -p:PublishAot=true
# Execute AOT compiled tests
.\bin\Release\net9.0\publish\MyApp.Tests.exe
```text
### IDE Integration
### Visual Studio 2022
- Version 17.13+ required
- Enable "Use testing platform server mode"
### VS Code
- Install C# Dev Kit extension
- Enable "Use Testing Platform Protocol"
### JetBrains Rider
- Enable "Testing Platform support"
---
## Performance Comparison
| Scenario | xUnit | TUnit | TUnit AOT | Performance Gain |
| -------- | ----- | ----- | --------- | ---------------- |
| **Simple Test Execution** | 1,400ms | 1,000ms | 60ms | 23x (AOT) |
| **Async Test** | 1,400ms | 930ms | 26ms | 54x (AOT) |
| **Parallel Test** | 1,425ms | 999ms | 54ms | 26x (AOT) |
---
## Common Issues and Solutions
### Issue 1: Package Compatibility
**Error:** Installed `Microsoft.NET.Test.Sdk` causing tests not discoverable
**Solution:** Remove `Microsoft.NET.Test.Sdk`, TUnit uses new testing platform
### Issue 2: IDE Integration Issues
**Symptom:** Tests not displaying or executing in IDE
### Solution
1. Confirm IDE version supports Microsoft.Testing.Platform
2. Enable relevant preview features
3. Reload project or restart IDE
### Issue 3: Async Assertion Forgotten
**Symptom:** Compilation errors or assertions not executing properly
**Solution:** All assertions need `await`, test methods must be `async Task`
---
## Applicable Scenario Assessment
### Suitable for TUnit
1. **New Projects**: No legacy baggage
2. **High Performance Requirements**: Large test suites (1000+ tests)
3. **Advanced Tech Stack**: Using .NET 8+, planning AOT adoption
4. **Heavy CI/CD Usage**: Test execution time directly impacts deployment frequency
5. **Containerized Deployment**: Fast startup time is important
### Not Recommended for Now
1. **Legacy Projects**: Already have large amounts of xUnit tests
2. **Conservative Teams**: Need stability over innovation
3. **Complex Test Ecosystem**: Heavy use of xUnit specific packages
4. **Old .NET Versions**: Still on .NET 6/7
---
## Reference Resources
### Original Articles
This skill content is distilled from the "Old School Software Engineer's Testing Practice - 30 Day Challenge" article series:
- **Day 28 - TUnit Introduction - Next Generation .NET Testing Framework Exploration**
- Article: https://ithelp.ithome.com.tw/articles/10377828
- Sample code: https://github.com/kevintsengtw/30Days_in_Testing_Samples/tree/main/day28
### Official Resources
- [TUnit Official Website](https://tunit.dev/)
- [TUnit GitHub](https://github.com/thomhurst/TUnit)
- [Migration from xUnit Guide](https://tunit.dev/docs/migration/xunit)
### Microsoft Official Documentation
- [Microsoft.Testing.Platform Introduction](https://learn.microsoft.com/dotnet/core/testing/microsoft-testing-platform-intro)
- [Native AOT Deployment](https://learn.microsoft.com/dotnet/core/deploying/native-aot)
1---2name: dotnet-testing-advanced-tunit-fundamentals3description: Complete guide for TUnit new-generation testing framework. Use when creating test projects with TUnit or migrating from xUnit to TUnit. Covers Source Generator driven test discovery, AOT compilation support, fluent async assertions. Includes project creation, [Test] attribute, lifecycle management, parallel control, and xUnit syntax comparison. Keywords: TUnit, tunit testing, source generator testing, AOT testing, new generation testing framework, [Test], [Arguments], TUnit.Assertions, Assert.That, Before(Test), After(Test), NotInParallel, TUnit.Templates, Microsoft.Testing.Platform, TUnit vs xUnit, parallel execution4---5Source: kevintsengtw/dotnet-testing-agent-skills (MIT). Ported into dotnet-agent-harness.67# TUnit New Generation Testing Framework Introduction89## Applicable Scenarios1011This skill covers TUnit new-generation .NET testing framework introduction basics, from framework features to actual12project creation and test writing.1314### Core Topics1516- TUnit framework features and design philosophy17- Source Generator driven test discovery18- AOT (Ahead-of-Time) compilation support19- Fluent async assertion system20- Project creation and package configuration21- Syntax differences compared to xUnit2223---2425## TUnit Framework Core Features2627### 1. Source Generator Driven Test Discovery2829TUnit's biggest difference from traditional testing frameworks is using Source Generator to complete test discovery at30**compile time**:3132### Traditional Framework Approach (xUnit)3334````csharp35// xUnit discovers all methods through reflection at runtime36public class TraditionalTests37{38 [Fact] // Only discovered at runtime39 public void TestMethod() { }40}41```text4243### TUnit's Innovative Approach4445```csharp46// TUnit generates test registration code at compile time through Source Generator47public class ModernTests48{49 [Test] // Processed and optimized at compile time50 public async Task TestMethod()51 {52 await Assert.That(true).IsTrue();53 }54}55```text5657### Advantages58591. Avoid reflection cost: All test discovery completed at compile time602. AOT compatible: Fully supports Native AOT compilation613. Faster startup time: Especially in large test projects6263### 2. AOT (Ahead-of-Time) Compilation Support6465### JIT vs AOT Compilation Flow6667```text68Traditional JIT: C# source → IL bytecode → JIT compile at runtime → machine code → execute69AOT: C# source → directly generate at compile time → machine code → execute directly70```text7172### AOT Compilation Advantages7374- Ultra-fast startup time (no waiting for JIT compilation)75- Smaller memory footprint76- Predictable performance77- More suitable for containerized deployment7879### Enable AOT Support8081```xml82<PropertyGroup>83 <PublishAot>true</PublishAot>84 <InvariantGlobalization>true</InvariantGlobalization>85</PropertyGroup>86```text8788### Actual Performance Differences8990```text91Traditional JIT compilation test startup time: ~1-2 seconds92TUnit AOT compilation test startup time: ~50-100 milliseconds93(Large projects can achieve 10-30x startup time improvement)94```text9596### 3. Microsoft.Testing.Platform Adoption9798TUnit is built on Microsoft's latest Microsoft.Testing.Platform, not the traditional VSTest platform:99100- Lighter test runner101- Better parallel control mechanism102- Native support for latest IDE integration103104### Important Notes105106TUnit projects **do not need** and **should not** install `Microsoft.NET.Test.Sdk` package.107108### 4. Default Parallel Execution109110TUnit sets parallel execution as default and provides fine-grained control:111112```csharp113// Default all tests execute in parallel114[Test]115public async Task ParallelTest1() { }116117[Test]118public async Task ParallelTest2() { }119120// Can control parallel behavior when needed121[Test]122[NotInParallel("DatabaseTests")]123public async Task DatabaseTest() { }124```text125126---127128## TUnit Project Creation129130### Method One: Manual Creation (Understanding Underlying Architecture)131132```bash133# Create project directory134mkdir TUnitDemo135cd TUnitDemo136137# Create solution138dotnet new sln -n MyApp139140# Create main project141dotnet new classlib -n MyApp.Core -o src/MyApp.Core142143# Create test project (use console template)144dotnet new console -n MyApp.Tests -o tests/MyApp.Tests145146# Add to solution147dotnet sln add src/MyApp.Core/MyApp.Core.csproj148dotnet sln add tests/MyApp.Tests/MyApp.Tests.csproj149150# Add project reference151dotnet add tests/MyApp.Tests/MyApp.Tests.csproj reference src/MyApp.Core/MyApp.Core.csproj152```text153154### Method Two: Using TUnit Template (Recommended)155156```bash157# Install TUnit project templates158dotnet new install TUnit.Templates159160# Create test project using TUnit template161dotnet new tunit -n MyApp.Tests -o tests/MyApp.Tests162```text163164### Test Project csproj Configuration165166```xml167<Project Sdk="Microsoft.NET.Sdk">168169 <PropertyGroup>170 <TargetFramework>net9.0</TargetFramework>171 <ImplicitUsings>enable</ImplicitUsings>172 <Nullable>enable</Nullable>173 <IsPackable>false</IsPackable>174 <IsTestProject>true</IsTestProject>175 </PropertyGroup>176177 <ItemGroup>178 <!-- TUnit core packages -->179 <PackageReference Include="TUnit" Version="0.57.24" />180 <!-- Code coverage support -->181 <PackageReference Include="Microsoft.Testing.Extensions.CodeCoverage" Version="17.12.4" />182 <!-- TRX report support -->183 <PackageReference Include="Microsoft.Testing.Extensions.TrxReport" Version="1.4.3" />184 </ItemGroup>185186 <ItemGroup>187 <ProjectReference Include="..\..\src\MyApp.Core\MyApp.Core.csproj" />188 </ItemGroup>189190</Project>191```text192193### GlobalUsings Configuration194195```csharp196// GlobalUsings.cs197global using TUnit.Core;198global using TUnit.Assertions;199global using MyApp.Core;200```text201202---203204## Async Test Methods (Required)205206TUnit **requires all test methods to be async**, this is a framework technical requirement:207208```csharp209// ❌ Error: won't compile210[Test]211public void WrongTest()212{213 Assert.That(1 + 1).IsEqualTo(2);214}215216// ✅ Correct: use async Task217[Test]218public async Task CorrectTest()219{220 await Assert.That(1 + 1).IsEqualTo(2);221}222```text223224---225226## Test Attributes and Parameterization227228### Basic Test [Test]229230TUnit uniformly uses `[Test]` attribute, unlike xUnit which distinguishes `[Fact]` and `[Theory]`:231232```csharp233// TUnit: uniformly use [Test]234[Test]235public async Task Add_Input1And2_ShouldReturn3()236{237 var calculator = new Calculator();238 var result = calculator.Add(1, 2);239 await Assert.That(result).IsEqualTo(3);240}241```text242243### Parameterized Tests [Arguments]244245```csharp246// TUnit: use [Arguments] (equivalent to xUnit's [InlineData])247[Test]248[Arguments(1, 2, 3)]249[Arguments(-1, 1, 0)]250[Arguments(0, 0, 0)]251[Arguments(100, -50, 50)]252public async Task Add_MultipleInputs_ShouldReturnCorrectResult(int a, int b, int expected)253{254 var calculator = new Calculator();255 var result = calculator.Add(a, b);256 await Assert.That(result).IsEqualTo(expected);257}258```text259260---261262## TUnit.Assertions Assertion System263264TUnit adopts fluent assertion design, all assertions are async. Supports equality, boolean, numeric comparison, string, collection, exception, and other assertions, and can combine conditions through `And` / `Or`.265266```csharp267// Basic usage examples268await Assert.That(actual).IsEqualTo(expected);269await Assert.That(email).Contains("@").And.EndsWith(".com");270await Assert.That(() => action()).Throws<InvalidOperationException>();271```text272273> 📖 Complete assertion types and examples please refer to [TUnit Assertion System Detailed Description](references/tunit-assertions-detail.md)274275---276277## Test Lifecycle Management278279TUnit supports constructor / `Dispose` pattern, and `[Before(Test)]`, `[Before(Class)]`, `[After(Test)]`, `[After(Class)]` and other attributes, providing more refined lifecycle control than xUnit.280281```text282Execution order: Before(Class) → Constructor → Before(Test) → Test Method → After(Test) → Dispose → After(Class)283```text284285> 📖 Complete lifecycle examples and attribute comparison table please refer to [Lifecycle Management Detailed Description](references/lifecycle-management.md)286287---288289## Parallel Execution Control290291### NotInParallel Attribute292293```csharp294// Default parallel execution295[Test]296public async Task ParallelTest1() { }297298[Test]299public async Task ParallelTest2() { }300301// Control specific tests not to run in parallel302[Test]303[NotInParallel("DatabaseTests")]304public async Task DatabaseTest1_NotInParallel()305{306 // This test won't run in parallel with other "DatabaseTests" group307}308309[Test]310[NotInParallel("DatabaseTests")]311public async Task DatabaseTest2_NotInParallel()312{313 // Runs sequentially with DatabaseTest1314}315```text316317---318319## xUnit to TUnit Syntax Comparison320321| Feature | xUnit | TUnit |322| ------- | ----- | ----- |323| **Basic Test** | `[Fact]` | `[Test]` |324| **Parameterized Test** | `[Theory]` + `[InlineData]` | `[Test]` + `[Arguments]` |325| **Basic Assertion** | `Assert.Equal(expected, actual)` | `await Assert.That(actual).IsEqualTo(expected)` |326| **Boolean Assertion** | `Assert.True(condition)` | `await Assert.That(condition).IsTrue()` |327| **Exception Test** | `Assert.Throws<T>(() => action())` | `await Assert.That(() => action()).Throws<T>()` |328| **Null Check** | `Assert.Null(value)` | `await Assert.That(value).IsNull()` |329| **String Check** | `Assert.Contains("text", fullString)` | `await Assert.That(fullString).Contains("text")` |330331### Migration Example332333### xUnit Original Code334335```csharp336[Theory]337[InlineData("test@example.com", true)]338[InlineData("invalid", false)]339public void IsValidEmail_VariousInputs_ShouldReturnCorrectValidationResult(string email, bool expected)340{341 var result = _validator.IsValidEmail(email);342 Assert.Equal(expected, result);343}344```text345346### TUnit Converted347348```csharp349[Test]350[Arguments("test@example.com", true)]351[Arguments("invalid", false)]352public async Task IsValidEmail_VariousInputs_ShouldReturnCorrectValidationResult(string email, bool expected)353{354 var result = _validator.IsValidEmail(email);355 await Assert.That(result).IsEqualTo(expected);356}357```text358359### Main Changes3603611. `[Theory]` → `[Test]`3622. `[InlineData]` → `[Arguments]`3633. Method changed to `async Task`3644. All assertions prefixed with `await`3655. Fluent assertion syntax366367---368369## Execution and Debugging370371### CLI Execution372373```bash374# Build project375dotnet build376377# Run all tests378dotnet test379380# Verbose output381dotnet test --verbosity normal382383# Generate coverage report384dotnet test --coverage385386# Filter specific tests387dotnet test --filter "ClassName=CalculatorTests"388dotnet test --filter "TestName~Add"389```text390391### AOT Compilation Execution392393```bash394# Publish as AOT compiled version395dotnet publish -c Release -p:PublishAot=true396397# Execute AOT compiled tests398.\bin\Release\net9.0\publish\MyApp.Tests.exe399```text400401### IDE Integration402403### Visual Studio 2022404405- Version 17.13+ required406- Enable "Use testing platform server mode"407408### VS Code409410- Install C# Dev Kit extension411- Enable "Use Testing Platform Protocol"412413### JetBrains Rider414415- Enable "Testing Platform support"416417---418419## Performance Comparison420421| Scenario | xUnit | TUnit | TUnit AOT | Performance Gain |422| -------- | ----- | ----- | --------- | ---------------- |423| **Simple Test Execution** | 1,400ms | 1,000ms | 60ms | 23x (AOT) |424| **Async Test** | 1,400ms | 930ms | 26ms | 54x (AOT) |425| **Parallel Test** | 1,425ms | 999ms | 54ms | 26x (AOT) |426427---428429## Common Issues and Solutions430431### Issue 1: Package Compatibility432433**Error:** Installed `Microsoft.NET.Test.Sdk` causing tests not discoverable434435**Solution:** Remove `Microsoft.NET.Test.Sdk`, TUnit uses new testing platform436437### Issue 2: IDE Integration Issues438439**Symptom:** Tests not displaying or executing in IDE440441### Solution4424431. Confirm IDE version supports Microsoft.Testing.Platform4442. Enable relevant preview features4453. Reload project or restart IDE446447### Issue 3: Async Assertion Forgotten448449**Symptom:** Compilation errors or assertions not executing properly450451**Solution:** All assertions need `await`, test methods must be `async Task`452453---454455## Applicable Scenario Assessment456457### Suitable for TUnit4584591. **New Projects**: No legacy baggage4602. **High Performance Requirements**: Large test suites (1000+ tests)4613. **Advanced Tech Stack**: Using .NET 8+, planning AOT adoption4624. **Heavy CI/CD Usage**: Test execution time directly impacts deployment frequency4635. **Containerized Deployment**: Fast startup time is important464465### Not Recommended for Now4664671. **Legacy Projects**: Already have large amounts of xUnit tests4682. **Conservative Teams**: Need stability over innovation4693. **Complex Test Ecosystem**: Heavy use of xUnit specific packages4704. **Old .NET Versions**: Still on .NET 6/7471472---473474## Reference Resources475476### Original Articles477478This skill content is distilled from the "Old School Software Engineer's Testing Practice - 30 Day Challenge" article series:479480- **Day 28 - TUnit Introduction - Next Generation .NET Testing Framework Exploration**481 - Article: https://ithelp.ithome.com.tw/articles/10377828482 - Sample code: https://github.com/kevintsengtw/30Days_in_Testing_Samples/tree/main/day28483484### Official Resources485486- [TUnit Official Website](https://tunit.dev/)487- [TUnit GitHub](https://github.com/thomhurst/TUnit)488- [Migration from xUnit Guide](https://tunit.dev/docs/migration/xunit)489490### Microsoft Official Documentation491492- [Microsoft.Testing.Platform Introduction](https://learn.microsoft.com/dotnet/core/testing/microsoft-testing-platform-intro)493- [Native AOT Deployment](https://learn.microsoft.com/dotnet/core/deploying/native-aot)494````