๐ The Modern Testing Framework for .NET
TUnit is a next-generation testing framework for C# that outpaces traditional frameworks with source-generated tests, parallel execution by default, and Native AOT support. Built on the modern Microsoft.Testing.Platform, TUnit delivers faster test runs, better developer experience, and unmatched flexibility.
โก Why Choose TUnit?
Feature | Traditional Frameworks | TUnit |
---|---|---|
Test Discovery | โ Runtime reflection | โ Compile-time generation |
Execution Speed | โ Sequential by default | โ Parallel by default |
Modern .NET | โ ๏ธ Limited AOT support | โ Full Native AOT & trimming |
Test Dependencies | โ Not supported | โ
[DependsOn] chains |
Resource Management | โ Manual lifecycle | โ Intelligent cleanup |
โก Parallel by Default - Tests run concurrently with intelligent dependency management
๐ฏ Compile-Time Discovery - Know your test structure before runtime
๐ง Modern .NET Ready - Native AOT, trimming, and latest .NET features
๐ญ Extensible - Customize data sources, attributes, and test behavior
๐ Complete Documentation & Learning Center
๐ New to TUnit? Start with our Getting Started Guide
๐ Migrating? See our Migration Guides
๐ฏ Advanced Features? Explore Data-Driven Testing, Test Dependencies, and Parallelism Control
๐ Quick Start
Using the Project Template (Recommended)
dotnet new install TUnit.Templates
dotnet new TUnit -n "MyTestProject"
Manual Installation
dotnet add package TUnit --prerelease
๐ ๐ Complete Documentation & Guides - Everything you need to master TUnit
โจ Key Features
๐ Performance & Modern Platform
|
๐ฏ Advanced Test Control
|
๐ Rich Data & Assertions
|
๐ง Developer Experience
|
๐ Simple Test Example
[Test]
public async Task User_Creation_Should_Set_Timestamp()
{
// Arrange
var userService = new UserService();
// Act
var user = await userService.CreateUserAsync("john.doe@example.com");
// Assert - TUnit's fluent assertions
await Assert.That(user.CreatedAt)
.IsEqualTo(DateTime.Now)
.Within(TimeSpan.FromMinutes(1));
await Assert.That(user.Email)
.IsEqualTo("john.doe@example.com");
}
๐ฏ Data-Driven Testing
[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 testing - tests all combinations
[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();
}
๐ Advanced Test Orchestration
[Before(Class)]
public static async Task SetupDatabase(ClassHookContext context)
{
await DatabaseHelper.InitializeAsync();
}
[Test, DisplayName("Register a new account")]
[MethodDataSource(nameof(GetTestUsers))]
public async Task Register_User(string username, string password)
{
// Test implementation
}
[Test, DependsOn(nameof(Register_User))]
[Retry(3)] // Retry on failure
public async Task Login_With_Registered_User(string username, string password)
{
// This test runs after Register_User completes
}
[Test]
[ParallelLimit<LoadTestParallelLimit>] // Custom parallel control
[Repeat(100)] // Run 100 times
public async Task Load_Test_Homepage()
{
// Performance testing
}
// Custom attributes
[Test, WindowsOnly, RetryOnHttpError(5)]
public async Task Windows_Specific_Feature()
{
// Platform-specific test with custom retry logic
}
public class LoadTestParallelLimit : IParallelLimit
{
public int Limit => 10; // Limit to 10 concurrent executions
}
๐ง Smart Test Control
// Custom conditional execution
public class WindowsOnlyAttribute : SkipAttribute
{
public WindowsOnlyAttribute() : base("Windows only test") { }
public override Task<bool> ShouldSkip(TestContext testContext)
=> Task.FromResult(!OperatingSystem.IsWindows());
}
// Custom retry logic
public class RetryOnHttpErrorAttribute : RetryAttribute
{
public RetryOnHttpErrorAttribute(int times) : base(times) { }
public override Task<bool> ShouldRetry(TestInformation testInformation,
Exception exception, int currentRetryCount)
=> Task.FromResult(exception is HttpRequestException { StatusCode: HttpStatusCode.ServiceUnavailable });
}
๐ฏ Perfect For Every Testing Scenario
๐งช Unit Testing
Fast, isolated, and reliable |
๐ Integration Testing
Stateful workflows made simple |
โก Load Testing
Built-in performance testing |
๐ What Makes TUnit Different?
Compile-Time Intelligence
Tests are discovered at build time, not runtime - enabling faster discovery, better IDE integration, and precise resource lifecycle management.
Parallel-First Architecture
Built for concurrency from day one with [DependsOn]
for test chains, [ParallelLimit]
for resource control, and intelligent scheduling.
Extensible by Design
The DataSourceGenerator<T>
pattern and custom attribute system let you extend TUnit's capabilities without modifying core framework code.
๐ Community & Ecosystem
๐ค Active Community
- ๐ Official Documentation - Comprehensive guides, tutorials, and API reference
- ๐ฌ GitHub Discussions - Get help and share ideas
- ๐ Issue Tracking - Report bugs and request features
- ๐ข Release Notes - Stay updated with latest improvements
๐ ๏ธ IDE Support
TUnit works seamlessly across all major .NET development environments:
Visual Studio (2022 17.13+)
โ Fully supported - No additional configuration needed for latest versions
โ๏ธ Earlier versions: Enable "Use testing platform server mode" in Tools > Manage Preview Features
JetBrains Rider
โ Fully supported
โ๏ธ Setup: Enable "Testing Platform support" in Settings > Build, Execution, Deployment > Unit Testing > VSTest
Visual Studio Code
โ Fully supported
โ๏ธ Setup: Install C# Dev Kit and enable "Use Testing Platform Protocol"
Command Line
โ
Full CLI support - Works with dotnet test
, dotnet run
, and direct executable execution
๐ฆ Package Options
Package | Use Case |
---|---|
TUnit |
โญ Start here - Complete testing framework (includes Core + Engine + Assertions) |
TUnit.Core |
๐ Test libraries and shared components (no execution engine) |
TUnit.Engine |
๐ Test execution engine and adapter (for test projects) |
TUnit.Assertions |
โ Standalone assertions (works with any test framework) |
TUnit.Playwright |
๐ญ Playwright integration with automatic lifecycle management |
๐ฏ Migration from Other Frameworks
Coming from NUnit or xUnit? TUnit maintains familiar syntax while adding modern capabilities:
// Enhanced with TUnit's advanced features
[Test]
[Arguments("value1")]
[Arguments("value2")]
[Retry(3)]
[ParallelLimit<CustomLimit>]
public async Task Modern_TUnit_Test(string value) { }
๐ Need help migrating? Check our detailed Migration Guides with step-by-step instructions for xUnit, NUnit, and MSTest.
๐ก Current Status
The API is mostly stable, but may have some changes based on feedback or issues before v1.0 release.
๐ Ready to Experience the Future of .NET Testing?
โก Start in 30 Seconds
# Create a new test project with examples
dotnet new install TUnit.Templates && dotnet new TUnit -n "MyAwesomeTests"
# Or add to existing project
dotnet add package TUnit --prerelease
๐ฏ Why Wait? Join the Movement
๐ PerformanceOptimized execution Parallel by default Zero reflection overhead |
๐ฎ Future-ReadyNative AOT support Latest .NET features Source generation |
๐ ๏ธ Developer ExperienceCompile-time checks Rich IDE integration Intelligent debugging |
๐ญ FlexibilityTest dependencies Custom attributes Extensible architecture |
๐ Learn More: tunit.dev | ๐ฌ Get Help: GitHub Discussions | โญ Show Support: Star on GitHub
TUnit is actively developed and production-ready. Join our growing community of developers who've made the switch!
Performance Benchmark
Scenario: Building the test project
macos-latest
BenchmarkDotNet v0.15.2, macOS Sequoia 15.6 (24G84) [Darwin 24.6.0]
Apple M1 (Virtual), 1 CPU, 3 logical and 3 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), Arm64 RyuJIT AdvSIMD
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), Arm64 RyuJIT AdvSIMD
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
Build_TUnit | 0.57.65 | 1.511 s | 0.1533 s | 0.4325 s | 1.365 s |
Build_NUnit | 4.4.0 | 1.621 s | 0.1212 s | 0.3498 s | 1.619 s |
Build_xUnit | 2.9.3 | 1.517 s | 0.1183 s | 0.3431 s | 1.426 s |
Build_MSTest | 3.10.4 | 1.648 s | 0.1234 s | 0.3620 s | 1.601 s |
ubuntu-latest
BenchmarkDotNet v0.15.2, Linux Ubuntu 24.04.3 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
Build_TUnit | 0.57.65 | 1.825 s | 0.0328 s | 0.0574 s | 1.802 s |
Build_NUnit | 4.4.0 | 1.513 s | 0.0180 s | 0.0159 s | 1.510 s |
Build_xUnit | 2.9.3 | 1.523 s | 0.0099 s | 0.0092 s | 1.521 s |
Build_MSTest | 3.10.4 | 1.517 s | 0.0094 s | 0.0083 s | 1.517 s |
windows-latest
BenchmarkDotNet v0.15.2, Windows 10 (10.0.20348.4052) (Hyper-V)
AMD EPYC 7763 2.44GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
Build_TUnit | 0.57.65 | 1.889 s | 0.0373 s | 0.0754 s | 1.871 s |
Build_NUnit | 4.4.0 | 1.591 s | 0.0193 s | 0.0171 s | 1.590 s |
Build_xUnit | 2.9.3 | 1.619 s | 0.0310 s | 0.0392 s | 1.610 s |
Build_MSTest | 3.10.4 | 1.610 s | 0.0287 s | 0.0268 s | 1.599 s |
Scenario: Tests focused on assertion performance and validation
macos-latest
BenchmarkDotNet v0.15.2, macOS Sequoia 15.6 (24G84) [Darwin 24.6.0]
Apple M1 (Virtual), 1 CPU, 3 logical and 3 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), Arm64 RyuJIT AdvSIMD
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), Arm64 RyuJIT AdvSIMD
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | NA | NA | NA | NA |
TUnit | 0.57.65 | NA | NA | NA | NA |
NUnit | 4.4.0 | NA | NA | NA | NA |
xUnit | 2.9.3 | NA | NA | NA | NA |
MSTest | 3.10.4 | NA | NA | NA | NA |
Benchmarks with issues: RuntimeBenchmarks.TUnit_AOT: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.TUnit: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.NUnit: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.xUnit: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.MSTest: Job-YNJDZW(Runtime=.NET 9.0)
ubuntu-latest
BenchmarkDotNet v0.15.2, Linux Ubuntu 24.04.3 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | NA | NA | NA | NA |
TUnit | 0.57.65 | NA | NA | NA | NA |
NUnit | 4.4.0 | NA | NA | NA | NA |
xUnit | 2.9.3 | NA | NA | NA | NA |
MSTest | 3.10.4 | NA | NA | NA | NA |
Benchmarks with issues: RuntimeBenchmarks.TUnit_AOT: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.TUnit: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.NUnit: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.xUnit: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.MSTest: Job-YNJDZW(Runtime=.NET 9.0)
windows-latest
BenchmarkDotNet v0.15.2, Windows 10 (10.0.20348.4052) (Hyper-V)
AMD EPYC 7763 2.44GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | NA | NA | NA | NA |
TUnit | 0.57.65 | NA | NA | NA | NA |
NUnit | 4.4.0 | NA | NA | NA | NA |
xUnit | 2.9.3 | NA | NA | NA | NA |
MSTest | 3.10.4 | NA | NA | NA | NA |
Benchmarks with issues: RuntimeBenchmarks.TUnit_AOT: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.TUnit: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.NUnit: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.xUnit: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.MSTest: Job-YNJDZW(Runtime=.NET 9.0)
Scenario: Tests running asynchronous operations and async/await patterns
macos-latest
BenchmarkDotNet v0.15.2, macOS Sequoia 15.6 (24G84) [Darwin 24.6.0]
Apple M1 (Virtual), 1 CPU, 3 logical and 3 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), Arm64 RyuJIT AdvSIMD
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), Arm64 RyuJIT AdvSIMD
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | 246.9 ms | 24.35 ms | 71.79 ms | 246.7 ms |
TUnit | 0.57.65 | 1,015.6 ms | 72.56 ms | 211.65 ms | 968.6 ms |
NUnit | 4.4.0 | 1,426.7 ms | 125.11 ms | 364.97 ms | 1,353.7 ms |
xUnit | 2.9.3 | 1,389.0 ms | 104.94 ms | 307.78 ms | 1,298.8 ms |
MSTest | 3.10.4 | 1,467.2 ms | 78.71 ms | 230.85 ms | 1,457.0 ms |
ubuntu-latest
BenchmarkDotNet v0.15.2, Linux Ubuntu 24.04.3 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | 28.40 ms | 0.261 ms | 0.231 ms | 28.43 ms |
TUnit | 0.57.65 | 956.42 ms | 18.967 ms | 21.082 ms | 950.66 ms |
NUnit | 4.4.0 | 1,349.53 ms | 15.744 ms | 13.957 ms | 1,348.72 ms |
xUnit | 2.9.3 | 1,456.35 ms | 26.979 ms | 27.705 ms | 1,449.97 ms |
MSTest | 3.10.4 | 1,302.83 ms | 19.019 ms | 16.859 ms | 1,301.11 ms |
windows-latest
BenchmarkDotNet v0.15.2, Windows 10 (10.0.20348.4052) (Hyper-V)
AMD EPYC 7763 2.44GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | 63.13 ms | 1.262 ms | 1.296 ms | 62.44 ms |
TUnit | 0.57.65 | 992.56 ms | 19.604 ms | 24.793 ms | 988.67 ms |
NUnit | 4.4.0 | 1,372.23 ms | 14.888 ms | 13.926 ms | 1,372.98 ms |
xUnit | 2.9.3 | 1,470.50 ms | 16.520 ms | 15.453 ms | 1,469.98 ms |
MSTest | 3.10.4 | 1,308.63 ms | 13.112 ms | 12.265 ms | 1,310.87 ms |
Scenario: Simple tests with basic operations and assertions
macos-latest
BenchmarkDotNet v0.15.2, macOS Sequoia 15.6 (24G84) [Darwin 24.6.0]
Apple M1 (Virtual), 1 CPU, 3 logical and 3 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), Arm64 RyuJIT AdvSIMD
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), Arm64 RyuJIT AdvSIMD
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | 195.9 ms | 21.53 ms | 63.14 ms | 175.8 ms |
TUnit | 0.57.65 | 1,052.3 ms | 75.71 ms | 223.23 ms | 1,023.1 ms |
NUnit | 4.4.0 | 1,438.3 ms | 138.37 ms | 405.81 ms | 1,376.3 ms |
xUnit | 2.9.3 | 1,387.7 ms | 91.45 ms | 268.20 ms | 1,352.5 ms |
MSTest | 3.10.4 | 1,443.9 ms | 82.10 ms | 239.50 ms | 1,424.0 ms |
ubuntu-latest
BenchmarkDotNet v0.15.2, Linux Ubuntu 24.04.3 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | 25.85 ms | 0.361 ms | 0.320 ms | 25.80 ms |
TUnit | 0.57.65 | 957.14 ms | 19.060 ms | 22.689 ms | 950.47 ms |
NUnit | 4.4.0 | 1,310.07 ms | 9.769 ms | 9.138 ms | 1,305.77 ms |
xUnit | 2.9.3 | 1,383.96 ms | 14.563 ms | 13.622 ms | 1,387.67 ms |
MSTest | 3.10.4 | 1,251.67 ms | 10.380 ms | 9.710 ms | 1,251.34 ms |
windows-latest
BenchmarkDotNet v0.15.2, Windows 10 (10.0.20348.4052) (Hyper-V)
AMD EPYC 7763 2.44GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | 62.20 ms | 0.597 ms | 0.529 ms | 62.36 ms |
TUnit | 0.57.65 | 1,101.86 ms | 21.606 ms | 32.995 ms | 1,108.25 ms |
NUnit | 4.4.0 | 1,519.96 ms | 29.731 ms | 34.238 ms | 1,525.15 ms |
xUnit | 2.9.3 | 1,579.46 ms | 31.501 ms | 30.938 ms | 1,582.17 ms |
MSTest | 3.10.4 | 1,460.47 ms | 27.903 ms | 28.654 ms | 1,457.01 ms |
Scenario: Parameterized tests with multiple test cases using data attributes
macos-latest
BenchmarkDotNet v0.15.2, macOS Sequoia 15.6 (24G84) [Darwin 24.6.0]
Apple M1 (Virtual), 1 CPU, 3 logical and 3 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), Arm64 RyuJIT AdvSIMD
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), Arm64 RyuJIT AdvSIMD
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | NA | NA | NA | NA |
TUnit | 0.57.65 | NA | NA | NA | NA |
NUnit | 4.4.0 | 869.5 ms | 25.52 ms | 74.84 ms | 864.7 ms |
xUnit | 2.9.3 | 893.7 ms | 14.42 ms | 12.78 ms | 892.3 ms |
MSTest | 3.10.4 | 824.3 ms | 16.16 ms | 30.75 ms | 827.2 ms |
Benchmarks with issues: RuntimeBenchmarks.TUnit_AOT: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.TUnit: Job-YNJDZW(Runtime=.NET 9.0)
ubuntu-latest
BenchmarkDotNet v0.15.2, Linux Ubuntu 24.04.3 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | NA | NA | NA | NA |
TUnit | 0.57.65 | NA | NA | NA | NA |
NUnit | 4.4.0 | 1.315 s | 0.0190 s | 0.0177 s | 1.312 s |
xUnit | 2.9.3 | 1.404 s | 0.0105 s | 0.0093 s | 1.406 s |
MSTest | 3.10.4 | 1.263 s | 0.0159 s | 0.0141 s | 1.265 s |
Benchmarks with issues: RuntimeBenchmarks.TUnit_AOT: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.TUnit: Job-YNJDZW(Runtime=.NET 9.0)
windows-latest
BenchmarkDotNet v0.15.2, Windows 10 (10.0.20348.4052) (Hyper-V)
AMD EPYC 7763 2.44GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | NA | NA | NA | NA |
TUnit | 0.57.65 | NA | NA | NA | NA |
NUnit | 4.4.0 | 1.372 s | 0.0158 s | 0.0140 s | 1.370 s |
xUnit | 2.9.3 | 1.462 s | 0.0147 s | 0.0138 s | 1.467 s |
MSTest | 3.10.4 | 1.319 s | 0.0101 s | 0.0079 s | 1.321 s |
Benchmarks with issues: RuntimeBenchmarks.TUnit_AOT: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.TUnit: Job-YNJDZW(Runtime=.NET 9.0)
Scenario: Tests utilizing class fixtures and shared test context
macos-latest
BenchmarkDotNet v0.15.2, macOS Sequoia 15.6 (24G84) [Darwin 24.6.0]
Apple M1 (Virtual), 1 CPU, 3 logical and 3 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), Arm64 RyuJIT AdvSIMD
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), Arm64 RyuJIT AdvSIMD
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | 282.8 ms | 23.36 ms | 68.88 ms | 292.7 ms |
TUnit | 0.57.65 | 1,021.2 ms | 74.27 ms | 217.82 ms | 981.7 ms |
NUnit | 4.4.0 | 1,135.5 ms | 30.24 ms | 87.26 ms | 1,129.8 ms |
xUnit | 2.9.3 | 1,214.0 ms | 37.97 ms | 104.58 ms | 1,221.6 ms |
MSTest | 3.10.4 | 963.0 ms | 33.33 ms | 90.67 ms | 951.2 ms |
ubuntu-latest
BenchmarkDotNet v0.15.2, Linux Ubuntu 24.04.3 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | 25.84 ms | 0.298 ms | 0.279 ms | 25.77 ms |
TUnit | 0.57.65 | 946.61 ms | 18.764 ms | 21.609 ms | 945.39 ms |
NUnit | 4.4.0 | 1,303.23 ms | 6.576 ms | 5.830 ms | 1,304.83 ms |
xUnit | 2.9.3 | 1,373.62 ms | 12.321 ms | 10.922 ms | 1,373.85 ms |
MSTest | 3.10.4 | NA | NA | NA | NA |
Benchmarks with issues: RuntimeBenchmarks.MSTest: Job-YNJDZW(Runtime=.NET 9.0)
windows-latest
BenchmarkDotNet v0.15.2, Windows 10 (10.0.20348.4052) (Hyper-V)
AMD EPYC 7763 2.44GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | 53.88 ms | 1.075 ms | 1.397 ms | 53.76 ms |
TUnit | 0.57.65 | 1,016.64 ms | 19.695 ms | 22.681 ms | 1,015.71 ms |
NUnit | 4.4.0 | 1,353.95 ms | 9.623 ms | 8.530 ms | 1,355.93 ms |
xUnit | 2.9.3 | 1,424.95 ms | 27.795 ms | 29.740 ms | 1,416.50 ms |
MSTest | 3.10.4 | NA | NA | NA | NA |
Benchmarks with issues: RuntimeBenchmarks.MSTest: Job-YNJDZW(Runtime=.NET 9.0)
Scenario: Tests executing in parallel to test framework parallelization
macos-latest
BenchmarkDotNet v0.15.2, macOS Sequoia 15.6 (24G84) [Darwin 24.6.0]
Apple M1 (Virtual), 1 CPU, 3 logical and 3 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), Arm64 RyuJIT AdvSIMD
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), Arm64 RyuJIT AdvSIMD
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | 156.1 ms | 8.28 ms | 24.28 ms | 149.5 ms |
TUnit | 0.57.65 | 1,003.4 ms | 75.85 ms | 216.40 ms | 967.4 ms |
NUnit | 4.4.0 | 1,538.4 ms | 142.24 ms | 417.17 ms | 1,423.0 ms |
xUnit | 2.9.3 | 1,243.9 ms | 58.92 ms | 170.94 ms | 1,242.2 ms |
MSTest | 3.10.4 | 1,273.8 ms | 110.74 ms | 317.74 ms | 1,223.6 ms |
ubuntu-latest
BenchmarkDotNet v0.15.2, Linux Ubuntu 24.04.3 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | 26.30 ms | 0.168 ms | 0.149 ms | 26.29 ms |
TUnit | 0.57.65 | 945.49 ms | 18.799 ms | 22.379 ms | 943.12 ms |
NUnit | 4.4.0 | 1,321.94 ms | 10.563 ms | 9.881 ms | 1,322.25 ms |
xUnit | 2.9.3 | 1,394.78 ms | 9.010 ms | 8.428 ms | 1,394.10 ms |
MSTest | 3.10.4 | 1,271.70 ms | 9.700 ms | 9.073 ms | 1,270.76 ms |
windows-latest
BenchmarkDotNet v0.15.2, Windows 10 (10.0.20348.4052) (Hyper-V)
AMD EPYC 7763 2.44GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | 61.76 ms | 1.043 ms | 0.976 ms | 62.36 ms |
TUnit | 0.57.65 | 1,050.87 ms | 20.881 ms | 24.047 ms | 1,049.79 ms |
NUnit | 4.4.0 | 1,429.72 ms | 13.654 ms | 12.104 ms | 1,433.31 ms |
xUnit | 2.9.3 | 1,446.62 ms | 17.306 ms | 16.188 ms | 1,443.57 ms |
MSTest | 3.10.4 | 1,318.66 ms | 12.503 ms | 11.695 ms | 1,319.96 ms |
Scenario: A test that takes 50ms to execute, repeated 100 times
macos-latest
BenchmarkDotNet v0.15.2, macOS Sequoia 15.6 (24G84) [Darwin 24.6.0]
Apple M1 (Virtual), 1 CPU, 3 logical and 3 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), Arm64 RyuJIT AdvSIMD
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), Arm64 RyuJIT AdvSIMD
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | NA | NA | NA | NA |
TUnit | 0.57.65 | NA | NA | NA | NA |
NUnit | 4.4.0 | NA | NA | NA | NA |
xUnit | 2.9.3 | NA | NA | NA | NA |
MSTest | 3.10.4 | NA | NA | NA | NA |
Benchmarks with issues: RuntimeBenchmarks.TUnit_AOT: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.TUnit: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.NUnit: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.xUnit: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.MSTest: Job-YNJDZW(Runtime=.NET 9.0)
ubuntu-latest
BenchmarkDotNet v0.15.2, Linux Ubuntu 24.04.3 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | NA | NA | NA | NA |
TUnit | 0.57.65 | NA | NA | NA | NA |
NUnit | 4.4.0 | NA | NA | NA | NA |
xUnit | 2.9.3 | NA | NA | NA | NA |
MSTest | 3.10.4 | NA | NA | NA | NA |
Benchmarks with issues: RuntimeBenchmarks.TUnit_AOT: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.TUnit: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.NUnit: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.xUnit: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.MSTest: Job-YNJDZW(Runtime=.NET 9.0)
windows-latest
BenchmarkDotNet v0.15.2, Windows 10 (10.0.20348.4052) (Hyper-V)
AMD EPYC 7763 2.44GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | NA | NA | NA | NA |
TUnit | 0.57.65 | NA | NA | NA | NA |
NUnit | 4.4.0 | NA | NA | NA | NA |
xUnit | 2.9.3 | NA | NA | NA | NA |
MSTest | 3.10.4 | NA | NA | NA | NA |
Benchmarks with issues: RuntimeBenchmarks.TUnit_AOT: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.TUnit: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.NUnit: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.xUnit: Job-YNJDZW(Runtime=.NET 9.0) RuntimeBenchmarks.MSTest: Job-YNJDZW(Runtime=.NET 9.0)
Scenario: Tests with setup and teardown lifecycle methods
macos-latest
BenchmarkDotNet v0.15.2, macOS Sequoia 15.6 (24G84) [Darwin 24.6.0]
Apple M1 (Virtual), 1 CPU, 3 logical and 3 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), Arm64 RyuJIT AdvSIMD
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), Arm64 RyuJIT AdvSIMD
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | 187.8 ms | 10.71 ms | 30.54 ms | 190.1 ms |
TUnit | 0.57.65 | 1,113.5 ms | 85.26 ms | 248.70 ms | 1,061.1 ms |
NUnit | 4.4.0 | 1,530.1 ms | 107.54 ms | 317.09 ms | 1,503.3 ms |
xUnit | 2.9.3 | 1,314.0 ms | 67.51 ms | 199.05 ms | 1,302.3 ms |
MSTest | 3.10.4 | 1,112.3 ms | 81.43 ms | 237.55 ms | 1,083.6 ms |
ubuntu-latest
BenchmarkDotNet v0.15.2, Linux Ubuntu 24.04.3 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | 26.88 ms | 0.154 ms | 0.129 ms | 26.86 ms |
TUnit | 0.57.65 | 964.14 ms | 18.784 ms | 18.448 ms | 969.71 ms |
NUnit | 4.4.0 | 1,329.60 ms | 9.400 ms | 8.793 ms | 1,333.00 ms |
xUnit | 2.9.3 | 1,395.85 ms | 8.020 ms | 7.502 ms | 1,396.99 ms |
MSTest | 3.10.4 | 1,276.36 ms | 8.271 ms | 7.736 ms | 1,276.65 ms |
windows-latest
BenchmarkDotNet v0.15.2, Windows 10 (10.0.20348.4171) (Hyper-V)
AMD EPYC 7763 2.44GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.305
[Host] : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.9 (9.0.925.41916), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.65 | 57.01 ms | 1.137 ms | 3.317 ms | 57.65 ms |
TUnit | 0.57.65 | 1,004.72 ms | 18.438 ms | 31.805 ms | 1,005.44 ms |
NUnit | 4.4.0 | 1,335.75 ms | 16.565 ms | 15.495 ms | 1,333.72 ms |
xUnit | 2.9.3 | 1,382.34 ms | 14.540 ms | 13.600 ms | 1,385.97 ms |
MSTest | 3.10.4 | 1,277.11 ms | 7.443 ms | 6.962 ms | 1,278.63 ms |