๐ 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 Sonoma 14.7.6 (23H626) [Darwin 23.6.0]
Apple M1 (Virtual), 1 CPU, 3 logical and 3 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), Arm64 RyuJIT AdvSIMD
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), Arm64 RyuJIT AdvSIMD
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
Build_TUnit | 0.57.1 | 1,220.4 ms | 88.48 ms | 242.2 ms | 1,149.9 ms |
Build_NUnit | 4.4.0 | 997.2 ms | 36.71 ms | 106.5 ms | 992.9 ms |
Build_xUnit | 2.9.3 | 1,452.9 ms | 83.47 ms | 242.2 ms | 1,435.1 ms |
Build_MSTest | 3.10.2 | 1,539.9 ms | 96.98 ms | 284.4 ms | 1,532.0 ms |
ubuntu-latest
BenchmarkDotNet v0.15.2, Linux Ubuntu 24.04.2 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
Build_TUnit | 0.57.1 | 1.834 s | 0.0316 s | 0.0410 s | 1.830 s |
Build_NUnit | 4.4.0 | 1.517 s | 0.0138 s | 0.0129 s | 1.513 s |
Build_xUnit | 2.9.3 | 1.542 s | 0.0123 s | 0.0109 s | 1.542 s |
Build_MSTest | 3.10.2 | 1.518 s | 0.0100 s | 0.0094 s | 1.518 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.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
Build_TUnit | 0.57.1 | 1.855 s | 0.0357 s | 0.0671 s | 1.840 s |
Build_NUnit | 4.4.0 | 1.566 s | 0.0198 s | 0.0175 s | 1.565 s |
Build_xUnit | 2.9.3 | 1.570 s | 0.0213 s | 0.0199 s | 1.570 s |
Build_MSTest | 3.10.2 | 1.595 s | 0.0287 s | 0.0331 s | 1.588 s |
Scenario: Tests focused on assertion performance and validation
macos-latest
BenchmarkDotNet v0.15.2, macOS Sonoma 14.7.6 (23H626) [Darwin 23.6.0]
Apple M1 (Virtual), 1 CPU, 3 logical and 3 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), Arm64 RyuJIT AdvSIMD
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), Arm64 RyuJIT AdvSIMD
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | NA | NA | NA | NA |
TUnit | 0.57.1 | NA | NA | NA | NA |
NUnit | 4.4.0 | NA | NA | NA | NA |
xUnit | 2.9.3 | NA | NA | NA | NA |
MSTest | 3.10.2 | 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.2 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | NA | NA | NA | NA |
TUnit | 0.57.1 | NA | NA | NA | NA |
NUnit | 4.4.0 | NA | NA | NA | NA |
xUnit | 2.9.3 | NA | NA | NA | NA |
MSTest | 3.10.2 | 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.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | NA | NA | NA | NA |
TUnit | 0.57.1 | NA | NA | NA | NA |
NUnit | 4.4.0 | NA | NA | NA | NA |
xUnit | 2.9.3 | NA | NA | NA | NA |
MSTest | 3.10.2 | 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 Sonoma 14.7.6 (23H626) [Darwin 23.6.0]
Apple M1 (Virtual), 1 CPU, 3 logical and 3 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), Arm64 RyuJIT AdvSIMD
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), Arm64 RyuJIT AdvSIMD
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | 110.9 ms | 7.28 ms | 20.41 ms | 102.5 ms |
TUnit | 0.57.1 | 939.6 ms | 73.56 ms | 215.73 ms | 959.9 ms |
NUnit | 4.4.0 | 1,389.4 ms | 118.70 ms | 348.12 ms | 1,326.2 ms |
xUnit | 2.9.3 | 1,084.7 ms | 45.19 ms | 131.11 ms | 1,048.3 ms |
MSTest | 3.10.2 | 1,057.8 ms | 69.56 ms | 204.00 ms | 1,025.1 ms |
ubuntu-latest
BenchmarkDotNet v0.15.2, Linux Ubuntu 24.04.2 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | 27.09 ms | 0.323 ms | 0.287 ms | 26.98 ms |
TUnit | 0.57.1 | 975.52 ms | 18.893 ms | 21.758 ms | 973.79 ms |
NUnit | 4.4.0 | 1,336.83 ms | 26.092 ms | 26.795 ms | 1,320.35 ms |
xUnit | 2.9.3 | 1,413.27 ms | 10.456 ms | 9.269 ms | 1,411.69 ms |
MSTest | 3.10.2 | 1,266.33 ms | 12.444 ms | 11.640 ms | 1,264.23 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.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | 62.76 ms | 0.785 ms | 0.696 ms | 62.42 ms |
TUnit | 0.57.1 | 1,008.80 ms | 20.048 ms | 21.452 ms | 1,008.32 ms |
NUnit | 4.4.0 | 1,396.27 ms | 19.145 ms | 16.972 ms | 1,400.31 ms |
xUnit | 2.9.3 | 1,491.64 ms | 15.560 ms | 13.793 ms | 1,493.34 ms |
MSTest | 3.10.2 | 1,330.56 ms | 23.373 ms | 21.863 ms | 1,333.67 ms |
Scenario: Simple tests with basic operations and assertions
macos-latest
BenchmarkDotNet v0.15.2, macOS Sonoma 14.7.6 (23H626) [Darwin 23.6.0]
Apple M1 (Virtual), 1 CPU, 3 logical and 3 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), Arm64 RyuJIT AdvSIMD
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), Arm64 RyuJIT AdvSIMD
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | 111.1 ms | 4.27 ms | 12.32 ms | 107.5 ms |
TUnit | 0.57.1 | 623.5 ms | 18.62 ms | 53.72 ms | 615.7 ms |
NUnit | 4.4.0 | 1,256.9 ms | 83.63 ms | 245.28 ms | 1,237.2 ms |
xUnit | 2.9.3 | 1,249.1 ms | 63.23 ms | 184.46 ms | 1,242.9 ms |
MSTest | 3.10.2 | 1,067.6 ms | 56.73 ms | 166.37 ms | 1,062.7 ms |
ubuntu-latest
BenchmarkDotNet v0.15.2, Linux Ubuntu 24.04.2 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | 26.59 ms | 0.204 ms | 0.170 ms | 26.54 ms |
TUnit | 0.57.1 | 949.32 ms | 18.430 ms | 21.224 ms | 937.25 ms |
NUnit | 4.4.0 | 1,327.41 ms | 18.359 ms | 17.173 ms | 1,329.31 ms |
xUnit | 2.9.3 | 1,397.75 ms | 23.425 ms | 20.766 ms | 1,394.89 ms |
MSTest | 3.10.2 | 1,273.94 ms | 12.963 ms | 12.125 ms | 1,271.18 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.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | 54.75 ms | 1.042 ms | 1.115 ms | 54.54 ms |
TUnit | 0.57.1 | 981.58 ms | 19.306 ms | 24.415 ms | 971.05 ms |
NUnit | 4.4.0 | 1,325.30 ms | 16.921 ms | 14.130 ms | 1,324.96 ms |
xUnit | 2.9.3 | 1,388.17 ms | 11.482 ms | 10.179 ms | 1,389.06 ms |
MSTest | 3.10.2 | 1,307.39 ms | 19.198 ms | 17.958 ms | 1,310.55 ms |
Scenario: Parameterized tests with multiple test cases using data attributes
macos-latest
BenchmarkDotNet v0.15.2, macOS Sonoma 14.7.6 (23H626) [Darwin 23.6.0]
Apple M1 (Virtual), 1 CPU, 3 logical and 3 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), Arm64 RyuJIT AdvSIMD
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), Arm64 RyuJIT AdvSIMD
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | NA | NA | NA | NA |
TUnit | 0.57.1 | NA | NA | NA | NA |
NUnit | 4.4.0 | 723.2 ms | 9.78 ms | 8.17 ms | 719.7 ms |
xUnit | 2.9.3 | 771.0 ms | 15.28 ms | 39.45 ms | 751.1 ms |
MSTest | 3.10.2 | 704.6 ms | 13.93 ms | 23.27 ms | 698.4 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.2 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | NA | NA | NA | NA |
TUnit | 0.57.1 | NA | NA | NA | NA |
NUnit | 4.4.0 | 1.308 s | 0.0113 s | 0.0106 s | 1.309 s |
xUnit | 2.9.3 | 1.390 s | 0.0168 s | 0.0157 s | 1.382 s |
MSTest | 3.10.2 | 1.250 s | 0.0108 s | 0.0096 s | 1.247 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.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | NA | NA | NA | NA |
TUnit | 0.57.1 | NA | NA | NA | NA |
NUnit | 4.4.0 | 1.350 s | 0.0153 s | 0.0143 s | 1.351 s |
xUnit | 2.9.3 | 1.395 s | 0.0165 s | 0.0154 s | 1.393 s |
MSTest | 3.10.2 | 1.300 s | 0.0147 s | 0.0137 s | 1.303 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 Sonoma 14.7.6 (23H626) [Darwin 23.6.0]
Apple M1 (Virtual), 1 CPU, 3 logical and 3 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), Arm64 RyuJIT AdvSIMD
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), Arm64 RyuJIT AdvSIMD
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | 88.27 ms | 1.178 ms | 0.984 ms | 87.78 ms |
TUnit | 0.57.1 | 555.87 ms | 10.332 ms | 23.322 ms | 547.48 ms |
NUnit | 4.4.0 | 716.44 ms | 10.411 ms | 10.692 ms | 715.04 ms |
xUnit | 2.9.3 | 741.69 ms | 14.189 ms | 11.849 ms | 736.54 ms |
MSTest | 3.10.2 | 709.85 ms | 13.400 ms | 31.057 ms | 697.22 ms |
ubuntu-latest
BenchmarkDotNet v0.15.2, Linux Ubuntu 24.04.2 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | 25.51 ms | 0.125 ms | 0.111 ms | 25.49 ms |
TUnit | 0.57.1 | 923.59 ms | 17.702 ms | 17.386 ms | 918.87 ms |
NUnit | 4.4.0 | 1,271.43 ms | 8.844 ms | 8.273 ms | 1,270.81 ms |
xUnit | 2.9.3 | 1,349.57 ms | 10.187 ms | 9.529 ms | 1,350.70 ms |
MSTest | 3.10.2 | 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.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | 54.94 ms | 1.084 ms | 1.409 ms | 55.29 ms |
TUnit | 0.57.1 | 1,016.26 ms | 19.923 ms | 24.468 ms | 1,010.88 ms |
NUnit | 4.4.0 | 1,352.60 ms | 9.883 ms | 9.244 ms | 1,353.02 ms |
xUnit | 2.9.3 | 1,418.69 ms | 20.987 ms | 18.604 ms | 1,416.50 ms |
MSTest | 3.10.2 | 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 Sonoma 14.7.6 (23H626) [Darwin 23.6.0]
Apple M1 (Virtual), 1 CPU, 3 logical and 3 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), Arm64 RyuJIT AdvSIMD
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), Arm64 RyuJIT AdvSIMD
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | 107.9 ms | 4.87 ms | 14.21 ms | 106.2 ms |
TUnit | 0.57.1 | 723.4 ms | 25.11 ms | 72.86 ms | 714.9 ms |
NUnit | 4.4.0 | 927.6 ms | 24.78 ms | 71.89 ms | 920.1 ms |
xUnit | 2.9.3 | 1,004.0 ms | 39.93 ms | 116.46 ms | 978.3 ms |
MSTest | 3.10.2 | 967.7 ms | 37.81 ms | 111.50 ms | 943.4 ms |
ubuntu-latest
BenchmarkDotNet v0.15.2, Linux Ubuntu 24.04.2 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | 25.79 ms | 0.504 ms | 0.472 ms | 25.75 ms |
TUnit | 0.57.1 | 922.62 ms | 17.932 ms | 19.931 ms | 919.51 ms |
NUnit | 4.4.0 | 1,284.17 ms | 13.039 ms | 12.196 ms | 1,282.97 ms |
xUnit | 2.9.3 | 1,365.56 ms | 18.995 ms | 16.839 ms | 1,359.79 ms |
MSTest | 3.10.2 | 1,227.36 ms | 7.347 ms | 6.872 ms | 1,229.48 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.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | 50.05 ms | 0.991 ms | 1.422 ms | 49.82 ms |
TUnit | 0.57.1 | 989.88 ms | 19.346 ms | 19.000 ms | 988.74 ms |
NUnit | 4.4.0 | 1,337.59 ms | 15.265 ms | 14.279 ms | 1,335.40 ms |
xUnit | 2.9.3 | 1,383.31 ms | 12.874 ms | 12.042 ms | 1,382.06 ms |
MSTest | 3.10.2 | 1,276.57 ms | 13.067 ms | 12.223 ms | 1,274.36 ms |
Scenario: A test that takes 50ms to execute, repeated 100 times
macos-latest
BenchmarkDotNet v0.15.2, macOS Sonoma 14.7.6 (23H626) [Darwin 23.6.0]
Apple M1 (Virtual), 1 CPU, 3 logical and 3 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), Arm64 RyuJIT AdvSIMD
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), Arm64 RyuJIT AdvSIMD
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | NA | NA | NA | NA |
TUnit | 0.57.1 | NA | NA | NA | NA |
NUnit | 4.4.0 | NA | NA | NA | NA |
xUnit | 2.9.3 | NA | NA | NA | NA |
MSTest | 3.10.2 | 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.2 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | NA | NA | NA | NA |
TUnit | 0.57.1 | NA | NA | NA | NA |
NUnit | 4.4.0 | NA | NA | NA | NA |
xUnit | 2.9.3 | NA | NA | NA | NA |
MSTest | 3.10.2 | 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.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | NA | NA | NA | NA |
TUnit | 0.57.1 | NA | NA | NA | NA |
NUnit | 4.4.0 | NA | NA | NA | NA |
xUnit | 2.9.3 | NA | NA | NA | NA |
MSTest | 3.10.2 | 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 Sonoma 14.7.6 (23H626) [Darwin 23.6.0]
Apple M1 (Virtual), 1 CPU, 3 logical and 3 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), Arm64 RyuJIT AdvSIMD
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), Arm64 RyuJIT AdvSIMD
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | 95.98 ms | 3.764 ms | 10.68 ms | 93.43 ms |
TUnit | 0.57.1 | 643.59 ms | 26.135 ms | 76.24 ms | 634.31 ms |
NUnit | 4.4.0 | 930.90 ms | 39.828 ms | 116.18 ms | 929.09 ms |
xUnit | 2.9.3 | 939.92 ms | 45.268 ms | 130.61 ms | 917.07 ms |
MSTest | 3.10.2 | 828.54 ms | 32.206 ms | 93.43 ms | 815.03 ms |
ubuntu-latest
BenchmarkDotNet v0.15.2, Linux Ubuntu 24.04.2 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | 26.27 ms | 0.257 ms | 0.215 ms | 26.27 ms |
TUnit | 0.57.1 | 948.21 ms | 18.772 ms | 21.618 ms | 950.46 ms |
NUnit | 4.4.0 | 1,308.78 ms | 11.724 ms | 10.967 ms | 1,310.83 ms |
xUnit | 2.9.3 | 1,387.95 ms | 10.475 ms | 9.798 ms | 1,391.03 ms |
MSTest | 3.10.2 | 1,253.72 ms | 12.530 ms | 11.721 ms | 1,255.48 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.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Job-YNJDZW : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
Runtime=.NET 9.0
Method | Version | Mean | Error | StdDev | Median |
---|---|---|---|---|---|
TUnit_AOT | 0.57.1 | 52.15 ms | 0.912 ms | 1.393 ms | 52.02 ms |
TUnit | 0.57.1 | 998.58 ms | 19.475 ms | 23.917 ms | 986.60 ms |
NUnit | 4.4.0 | 1,342.22 ms | 12.324 ms | 11.528 ms | 1,341.87 ms |
xUnit | 2.9.3 | 1,388.21 ms | 15.067 ms | 14.093 ms | 1,385.22 ms |
MSTest | 3.10.2 | 1,282.83 ms | 12.430 ms | 11.627 ms | 1,281.94 ms |