TUnit by Tom Longhurst
- NuGet / site data
- Details
- Why TUnit?
- Documentation
- Quick Start
- Key Features
- Simple Test Example
- Data-Driven Testing
- Advanced Test Orchestration
- Custom Test Control
- Common Use Cases
- What Makes TUnit Different?
- Community & Ecosystem
- IDE Support
- Package Options
- Migration from Other Frameworks
- Getting Started
- Performance Benchmark
- How to use
- Useful
NuGet / site data
Details
Info
Name: TUnit
Author: Tom Longhurst
NuGet: https://www.nuget.org/packages/TUnit/
You can find more details at https://github.com/thomhurst/TUnit
Author
Tom Longhurst

Original Readme

🚀 The Modern Testing Framework for .NET
TUnit is a modern testing framework for .NET that uses source-generated tests, parallel execution by default, and Native AOT support. Built on Microsoft.Testing.Platform, it's faster than traditional reflection-based frameworks and gives you more control over how your tests run.
Why 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 | ✅ Native AOT & trimming |
| Test Dependencies | ❌ Not supported | ✅ [DependsOn] chains |
| Resource Management | ❌ Manual lifecycle | ✅ Automatic cleanup |
Parallel by Default - Tests run concurrently with dependency management
Compile-Time Discovery - Test structure is known before runtime
Modern .NET Ready - Native AOT, trimming, and latest .NET features
Extensible - Customize data sources, attributes, and test behavior
Documentation
New to TUnit? Start with the Getting Started Guide
Migrating? See the Migration Guides
Learn more: Data-Driven Testing, Test Dependencies, 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
Key Features
Performance
| Test Control
|
Data & Assertions
| Developer Tools
|
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
}
Custom 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 });
}
Common Use Cases
Unit Testing | Integration Testing | Load Testing |
What Makes TUnit Different?
Compile-Time Test Discovery
Tests are discovered at build time, not runtime. This means faster discovery, better IDE integration, and more predictable resource management.
Parallel by Default
Tests run in parallel by default. Use [DependsOn] to chain tests together, and [ParallelLimit] to control resource usage.
Extensible
The DataSourceGenerator<T> pattern and custom attribute system let you extend TUnit without modifying the framework.
Community & Ecosystem
Resources
- Official Documentation - Guides, tutorials, and API reference
- GitHub Discussions - Get help and share ideas
- Issue Tracking - Report bugs and request features
- Release Notes - Latest updates and changes
IDE Support
TUnit works with all major .NET IDEs:
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 > Testing Platform
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 uses familiar syntax with some additions:
// TUnit test with dependency management and retries
[Test]
[Arguments("value1")]
[Arguments("value2")]
[Retry(3)]
[ParallelLimit<CustomLimit>]
public async Task Modern_TUnit_Test(string value) \{ }
📖 Need help migrating? Check our Migration Guides for xUnit, NUnit, and MSTest.
Getting Started
# Create a new test project
dotnet new install TUnit.Templates && dotnet new TUnit -n "MyTestProject"
# Or add to existing project
dotnet add package TUnit --prerelease
Learn More: tunit.dev | Get Help: GitHub Discussions | Star on GitHub: github.com/thomhurst/TUnit
Performance Benchmark
Scenario: Building the test project
BenchmarkDotNet v0.15.6, Linux Ubuntu 24.04.3 LTS (Noble Numbat)
AMD EPYC 7763 2.45GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.100-rc.2.25502.107
[Host] : .NET 10.0.0 (10.0.0-rc.2.25502.107, 10.0.25.50307), X64 RyuJIT x86-64-v3
Job-GVKUBM : .NET 10.0.0 (10.0.0-rc.2.25502.107, 10.0.25.50307), X64 RyuJIT x86-64-v3
Runtime=.NET 10.0
| Method | Version | Mean | Error | StdDev | Median |
|---|---|---|---|---|---|
| Build_TUnit | 1.0.48 | 1.798 s | 0.0345 s | 0.0424 s | 1.785 s |
| Build_NUnit | 4.4.0 | 1.575 s | 0.0169 s | 0.0158 s | 1.573 s |
| Build_MSTest | 4.0.1 | 1.659 s | 0.0150 s | 0.0140 s | 1.658 s |
| Build_xUnit3 | 3.2.0 | 1.579 s | 0.0182 s | 0.0170 s | 1.575 s |
Scenario: Tests running asynchronous operations and async/await patterns
BenchmarkDotNet v0.15.6, Linux Ubuntu 24.04.3 LTS (Noble Numbat)
AMD EPYC 7763 2.45GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.100-rc.2.25502.107
[Host] : .NET 10.0.0 (10.0.0-rc.2.25502.107, 10.0.25.50307), X64 RyuJIT x86-64-v3
Job-GVKUBM : .NET 10.0.0 (10.0.0-rc.2.25502.107, 10.0.25.50307), X64 RyuJIT x86-64-v3
Runtime=.NET 10.0
| Method | Version | Mean | Error | StdDev | Median |
|---|---|---|---|---|---|
| TUnit | 1.0.48 | 562.4 ms | 4.18 ms | 3.91 ms | 561.0 ms |
| NUnit | 4.4.0 | 679.2 ms | 7.24 ms | 6.41 ms | 679.6 ms |
| MSTest | 4.0.1 | 647.7 ms | 8.63 ms | 7.65 ms | 647.8 ms |
| xUnit3 | 3.2.0 | 744.4 ms | 11.90 ms | 10.55 ms | 741.5 ms |
| TUnit_AOT | 1.0.48 | 127.6 ms | 0.45 ms | 0.42 ms | 127.6 ms |
Scenario: Parameterized tests with multiple test cases using data attributes
BenchmarkDotNet v0.15.6, Linux Ubuntu 24.04.3 LTS (Noble Numbat)
AMD EPYC 7763 2.45GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.100-rc.2.25502.107
[Host] : .NET 10.0.0 (10.0.0-rc.2.25502.107, 10.0.25.50307), X64 RyuJIT x86-64-v3
Job-GVKUBM : .NET 10.0.0 (10.0.0-rc.2.25502.107, 10.0.25.50307), X64 RyuJIT x86-64-v3
Runtime=.NET 10.0
| Method | Version | Mean | Error | StdDev | Median |
|---|---|---|---|---|---|
| TUnit | 1.0.48 | 476.97 ms | 5.430 ms | 5.080 ms | 478.26 ms |
| NUnit | 4.4.0 | 537.80 ms | 6.692 ms | 6.260 ms | 537.55 ms |
| MSTest | 4.0.1 | 496.84 ms | 9.188 ms | 8.145 ms | 496.37 ms |
| xUnit3 | 3.2.0 | 584.15 ms | 10.733 ms | 10.039 ms | 582.13 ms |
| TUnit_AOT | 1.0.48 | 24.65 ms | 0.177 ms | 0.157 ms | 24.68 ms |
Scenario: Tests executing massively parallel workloads with CPU-bound, I/O-bound, and mixed operations
BenchmarkDotNet v0.15.6, Linux Ubuntu 24.04.3 LTS (Noble Numbat)
AMD EPYC 7763 2.45GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.100-rc.2.25502.107
[Host] : .NET 10.0.0 (10.0.0-rc.2.25502.107, 10.0.25.50307), X64 RyuJIT x86-64-v3
Job-GVKUBM : .NET 10.0.0 (10.0.0-rc.2.25502.107, 10.0.25.50307), X64 RyuJIT x86-64-v3
Runtime=.NET 10.0
| Method | Version | Mean | Error | StdDev | Median |
|---|---|---|---|---|---|
| TUnit | 1.0.48 | 578.1 ms | 5.79 ms | 5.13 ms | 577.3 ms |
| NUnit | 4.4.0 | 1,220.5 ms | 7.43 ms | 6.20 ms | 1,220.9 ms |
| MSTest | 4.0.1 | 3,005.3 ms | 13.91 ms | 12.33 ms | 3,003.4 ms |
| xUnit3 | 3.2.0 | 3,096.0 ms | 11.11 ms | 10.40 ms | 3,094.6 ms |
| TUnit_AOT | 1.0.48 | 130.6 ms | 0.39 ms | 0.36 ms | 130.7 ms |
Scenario: Tests with complex parameter combinations creating 25-125 test variations
BenchmarkDotNet v0.15.6, Linux Ubuntu 24.04.3 LTS (Noble Numbat)
AMD EPYC 7763 2.45GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.100-rc.2.25502.107
[Host] : .NET 10.0.0 (10.0.0-rc.2.25502.107, 10.0.25.50307), X64 RyuJIT x86-64-v3
Job-GVKUBM : .NET 10.0.0 (10.0.0-rc.2.25502.107, 10.0.25.50307), X64 RyuJIT x86-64-v3
Runtime=.NET 10.0
| Method | Version | Mean | Error | StdDev | Median |
|---|---|---|---|---|---|
| TUnit | 1.0.48 | 544.97 ms | 5.561 ms | 4.930 ms | 544.99 ms |
| NUnit | 4.4.0 | 1,540.60 ms | 5.644 ms | 4.713 ms | 1,540.91 ms |
| MSTest | 4.0.1 | 1,499.17 ms | 4.590 ms | 3.833 ms | 1,499.42 ms |
| xUnit3 | 3.2.0 | 1,591.72 ms | 6.560 ms | 6.136 ms | 1,592.55 ms |
| TUnit_AOT | 1.0.48 | 79.41 ms | 0.252 ms | 0.236 ms | 79.48 ms |
Scenario: Large-scale parameterized tests with 100+ test cases testing framework scalability
BenchmarkDotNet v0.15.6, Linux Ubuntu 24.04.3 LTS (Noble Numbat)
AMD EPYC 7763 2.45GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.100-rc.2.25502.107
[Host] : .NET 10.0.0 (10.0.0-rc.2.25502.107, 10.0.25.50307), X64 RyuJIT x86-64-v3
Job-GVKUBM : .NET 10.0.0 (10.0.0-rc.2.25502.107, 10.0.25.50307), X64 RyuJIT x86-64-v3
Runtime=.NET 10.0
| Method | Version | Mean | Error | StdDev | Median |
|---|---|---|---|---|---|
| TUnit | 1.0.48 | 498.22 ms | 7.188 ms | 6.723 ms | 496.45 ms |
| NUnit | 4.4.0 | 584.65 ms | 11.669 ms | 11.461 ms | 582.38 ms |
| MSTest | 4.0.1 | 580.53 ms | 11.233 ms | 15.747 ms | 583.58 ms |
| xUnit3 | 3.2.0 | 587.89 ms | 8.750 ms | 7.757 ms | 586.15 ms |
| TUnit_AOT | 1.0.48 | 46.75 ms | 1.442 ms | 4.253 ms | 47.33 ms |
About
Writing unit tests
How to use
Example (source csproj, source files)
- CSharp Project
- FirstTest.cs
This is the CSharp Project that references TUnit
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TUnit" Version="1.2.11" />
</ItemGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
</Project>
This is the use of TUnit in FirstTest.cs
namespace TestDemo;
public class FirstTest
{
[Test]
public async Task Add_WithTwoNumbers_ReturnsSum()
{
var result = true;
// Assert
await Assert.That(result).IsTrue();
}
}
Generated Files
Those are taken from $(BaseIntermediateOutputPath)\GX
- AssemblyLoader.g.cs
- DisableReflectionScanner.g.cs
- AotConverters.g.cs
- TestDemo_FirstTest_Add_WithTwoNumbers_ReturnsSum.g.cs
// <auto-generated/>
#pragma warning disable
[global::System.CodeDom.Compiler.GeneratedCode("TUnit", "1.0.0.0")]
file static class AssemblyLoader0fc44d9acf154c74aee2a9e062a8edcd
{
[global::System.Runtime.CompilerServices.ModuleInitializer]
public static void Initialize()
{
global::TUnit.Core.SourceRegistrar.RegisterAssembly(() => global::System.Reflection.Assembly.Load("EnumerableAsyncProcessor, Version=3.8.4.0, Culture=neutral, PublicKeyToken=7a7adb9c614908c9"));
global::TUnit.Core.SourceRegistrar.RegisterAssembly(() => global::System.Reflection.Assembly.Load("Microsoft.Extensions.DependencyModel, Version=6.0.0.2, Culture=neutral, PublicKeyToken=adb9793829ddae60"));
global::TUnit.Core.SourceRegistrar.RegisterAssembly(() => global::System.Reflection.Assembly.Load("Mono.Cecil, Version=0.11.5.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e"));
global::TUnit.Core.SourceRegistrar.RegisterAssembly(() => global::System.Reflection.Assembly.Load("Mono.Cecil.Mdb, Version=0.11.5.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e"));
global::TUnit.Core.SourceRegistrar.RegisterAssembly(() => global::System.Reflection.Assembly.Load("Mono.Cecil.Pdb, Version=0.11.5.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e"));
global::TUnit.Core.SourceRegistrar.RegisterAssembly(() => global::System.Reflection.Assembly.Load("Mono.Cecil.Rocks, Version=0.11.5.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e"));
global::TUnit.Core.SourceRegistrar.RegisterAssembly(() => global::System.Reflection.Assembly.Load("TUnit.Assertions, Version=1.2.11.0, Culture=neutral, PublicKeyToken=b8d4030011dbd70c"));
global::TUnit.Core.SourceRegistrar.RegisterAssembly(() => global::System.Reflection.Assembly.Load("TUnit.Core, Version=1.2.11.0, Culture=neutral, PublicKeyToken=b8d4030011dbd70c"));
global::TUnit.Core.SourceRegistrar.RegisterAssembly(() => global::System.Reflection.Assembly.Load("TUnit, Version=1.2.11.0, Culture=neutral, PublicKeyToken=b8d4030011dbd70c"));
global::TUnit.Core.SourceRegistrar.RegisterAssembly(() => global::System.Reflection.Assembly.Load("TUnit.Engine, Version=1.2.11.0, Culture=neutral, PublicKeyToken=b8d4030011dbd70c"));
}
}
// <auto-generated/>
#pragma warning disable
[global::System.CodeDom.Compiler.GeneratedCode("TUnit", "1.0.0.0")]
file static class DisableReflectionScanner_74bd22630f9848fb858269b3a1b085a4
{
[global::System.Runtime.CompilerServices.ModuleInitializer]
public static void Initialize()
{
global::TUnit.Core.SourceRegistrar.IsEnabled = true;
}
}
// <auto-generated/>
#pragma warning disable
#nullable enable
// No conversion operators found
// <auto-generated/>
#pragma warning disable
#nullable enable
namespace TUnit.Generated;
internal sealed class TestDemo_FirstTest_Add_WithTwoNumbers_ReturnsSum_TestSource : global::TUnit.Core.Interfaces.SourceGenerator.ITestSource
{
public async global::System.Collections.Generic.IAsyncEnumerable<global::TUnit.Core.TestMetadata> GetTestsAsync(string testSessionId, [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default)
{
var metadata = new global::TUnit.Core.TestMetadata<global::TestDemo.FirstTest>
{
TestName = "Add_WithTwoNumbers_ReturnsSum",
TestClassType = typeof(global::TestDemo.FirstTest),
TestMethodName = "Add_WithTwoNumbers_ReturnsSum",
Dependencies = global::System.Array.Empty<global::TUnit.Core.TestDependency>(),
AttributeFactory = static () =>
[
new global::TUnit.Core.TestAttribute(),
new global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v10.0")
{FrameworkDisplayName = ".NET 10.0",},
new global::System.Reflection.AssemblyCompanyAttribute("TestDemo"),
new global::System.Reflection.AssemblyConfigurationAttribute("Debug"),
new global::System.Reflection.AssemblyFileVersionAttribute("1.0.0.0"),
new global::System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+54e5188c456ecd37fa9b7fa05bc1869fe84e7d42"),
new global::System.Reflection.AssemblyProductAttribute("TestDemo"),
new global::System.Reflection.AssemblyTitleAttribute("TestDemo"),
new global::System.Reflection.AssemblyVersionAttribute("1.0.0.0"),
new global::System.Reflection.AssemblyMetadataAttribute("Microsoft.Testing.Platform.Application", "true")
],
DataSources = global::System.Array.Empty<global::TUnit.Core.IDataSourceAttribute>(),
ClassDataSources = global::System.Array.Empty<global::TUnit.Core.IDataSourceAttribute>(),
PropertyDataSources = global::System.Array.Empty<global::TUnit.Core.PropertyDataSource>(),
PropertyInjections = global::System.Array.Empty<global::TUnit.Core.PropertyInjectionData>(),
InheritanceDepth = 0,
FilePath = @"D:\\gth\\RSCG_Examples\\v2\\rscg_examples\\TUnit\\src\\TestDemo\\TestDemo\\FirstTest.cs",
LineNumber = 6,
MethodMetadata = new global::TUnit.Core.MethodMetadata
{
Type = typeof(global::TestDemo.FirstTest),
TypeInfo = new global::TUnit.Core.ConcreteType(typeof(global::TestDemo.FirstTest)),
Name = "Add_WithTwoNumbers_ReturnsSum",
GenericTypeCount = 0,
ReturnType = typeof(global::System.Threading.Tasks.Task),
ReturnTypeInfo = new global::TUnit.Core.ConcreteType(typeof(global::System.Threading.Tasks.Task)),
Parameters = global::System.Array.Empty<global::TUnit.Core.ParameterMetadata>(),
Class = global::TUnit.Core.ClassMetadata.GetOrAdd("TestDemo:global::TestDemo.FirstTest", static () =>
{
var classMetadata = new global::TUnit.Core.ClassMetadata
{
Type = typeof(global::TestDemo.FirstTest),
TypeInfo = new global::TUnit.Core.ConcreteType(typeof(global::TestDemo.FirstTest)),
Name = "FirstTest",
Namespace = "TestDemo",
Assembly = global::TUnit.Core.AssemblyMetadata.GetOrAdd("TestDemo", static () => new global::TUnit.Core.AssemblyMetadata \{ Name = "TestDemo" }),
Parameters = global::System.Array.Empty<global::TUnit.Core.ParameterMetadata>(),
Properties = global::System.Array.Empty<global::TUnit.Core.PropertyMetadata>(),
Parent = null
};
foreach (var prop in classMetadata.Properties)
{
prop.ClassMetadata = classMetadata;
prop.ContainingTypeMetadata = classMetadata;
}
return classMetadata;
})
},
InstanceFactory = (typeArgs, args) => new global::TestDemo.FirstTest(),
InvokeTypedTest = static (instance, args, cancellationToken) =>
{
try
{
return new global::System.Threading.Tasks.ValueTask(instance.Add_WithTwoNumbers_ReturnsSum());
}
catch (global::System.Exception ex)
{
return new global::System.Threading.Tasks.ValueTask(global::System.Threading.Tasks.Task.FromException(ex));
}
},
};
metadata.UseRuntimeDataGeneration(testSessionId);
yield return metadata;
yield break;
}
}
internal static class TestDemo_FirstTest_Add_WithTwoNumbers_ReturnsSum_ModuleInitializer
{
[global::System.Runtime.CompilerServices.ModuleInitializer]
public static void Initialize()
{
global::TUnit.Core.SourceRegistrar.Register(typeof(global::TestDemo.FirstTest), new TestDemo_FirstTest_Add_WithTwoNumbers_ReturnsSum_TestSource());
}
}
Useful
Download Example (.NET C#)
Share TUnit
https://ignatandrei.github.io/RSCG_Examples/v2/docs/TUnit
Category "Tests" has the following generators:
1 mocklis
2024-01-03
2 MockMe
2025-02-10
3 MSTest
2024-04-04
4 Ridge
2023-08-20
5 Rocks
2023-04-16
6 TUnit
2025-11-08