# TUnit > Fast, modern .NET testing This file contains links to documentation sections following the llmstxt.org standard. ## Table of Contents - [Awaiting](https://tunit.dev/docs/assertions/awaiting): In TUnit you `await` your assertions, and this serves two purposes: - [Boolean Assertions](https://tunit.dev/docs/assertions/boolean): TUnit provides simple, expressive assertions for testing boolean values. These assertions work with both `bool` and `bool?` (nullable boolean) types. - [Collection Assertions](https://tunit.dev/docs/assertions/collections): TUnit provides comprehensive assertions for testing collections, including membership, count, ordering, and equivalency checks. These assertions wo... - [Combining Assertions](https://tunit.dev/docs/assertions/combining-assertions): TUnit provides several ways to combine multiple assertions within a single test: chaining with `.And` and `.Or`, and grouping with `Assert.Multiple... - [DateTime and Time Assertions](https://tunit.dev/docs/assertions/datetime): TUnit provides comprehensive assertions for date and time types, including `DateTime`, `DateTimeOffset`, `DateOnly`, `TimeOnly`, and `TimeSpan`, wi... - [Delegates](https://tunit.dev/docs/assertions/delegates): TUnit can execute your delegates for you, and this allows you to assert on the data returned (if any was) - Or on any exceptions thrown: - [Dictionary Assertions](https://tunit.dev/docs/assertions/dictionaries): TUnit provides specialized assertions for testing dictionaries (`IReadOnlyDictionary`), including key and value membership checks. Di... - [Equality and Comparison Assertions](https://tunit.dev/docs/assertions/equality-and-comparison): TUnit provides comprehensive assertions for testing equality and comparing values. These assertions work with any type that implements the appropri... - [Exception Assertions](https://tunit.dev/docs/assertions/exceptions): TUnit provides comprehensive assertions for testing that code throws (or doesn't throw) exceptions, with rich support for validating exception type... - [Custom Assertions](https://tunit.dev/docs/assertions/extensibility/custom-assertions): The TUnit Assertions can be easily extended so that you can create your own assertions. - [Chaining and Converting](https://tunit.dev/docs/assertions/extensibility/extensibility-chaining-and-converting): TUnit allows you to chain assertions that change the type being asserted, enabling fluent and expressive test code. - [Returning Data via `await`](https://tunit.dev/docs/assertions/extensibility/extensibility-returning-items-from-await): Sometimes, you may want your assertion to return a value, such as an item found in a collection, so you can use it in further assertions or logic. - [Source Generator Assertions](https://tunit.dev/docs/assertions/extensibility/source-generator-assertions): TUnit provides source generators to simplify creating custom assertions. Instead of manually writing assertion classes and extension methods, you c... - [FSharp](https://tunit.dev/docs/assertions/fsharp): As awaiting doesn't work quite the same in F#, the syntax instead looks like this: - [Getting Started with Assertions](https://tunit.dev/docs/assertions/getting-started): TUnit provides a comprehensive, fluent assertion library that makes your tests readable and expressive. This guide introduces the core concepts and... - [Assertions Library](https://tunit.dev/docs/assertions/library): Searchable library of all TUnit assertions - [Member Assertions](https://tunit.dev/docs/assertions/member-assertions): The `.Member()` method allows you to assert on object properties while maintaining the parent object's context for chaining. This is useful when yo... - [Null and Default Value Assertions](https://tunit.dev/docs/assertions/null-and-default): TUnit provides assertions for testing null values and default values. These assertions integrate with C#'s nullability annotations to provide bette... - [Numeric Assertions](https://tunit.dev/docs/assertions/numeric): TUnit provides comprehensive assertions for testing numeric values, including specialized assertions for positive/negative values and comparison as... - [Regex Assertions](https://tunit.dev/docs/assertions/regex-assertions): The `.Matches()` method allows you to validate strings against regular expressions and assert on capture groups, match positions, and match lengths... - [Should Syntax (Optional)](https://tunit.dev/docs/assertions/should-syntax): FluentAssertions-style value.Should().BeEqualTo() syntax via the optional TUnit.Assertions.Should NuGet package. - [Specialized Type Assertions](https://tunit.dev/docs/assertions/specialized-types): TUnit provides assertions for many specialized .NET types beyond the common primitives. This page covers GUID, HTTP, file system, networking, and o... - [String Assertions](https://tunit.dev/docs/assertions/string): TUnit provides rich assertions for testing strings, including substring matching, pattern matching, length checks, and various string comparison op... - [Task and Async Assertions](https://tunit.dev/docs/assertions/tasks-and-async): TUnit provides specialized assertions for testing `Task` and `Task` objects, including state checking, completion timeouts, and async exception ... - [Type Checking](https://tunit.dev/docs/assertions/type-checking): TUnit assertions check types at compile time wherever possible. This gives faster feedback and catches mistakes before your build pipeline runs. - [Type Assertions](https://tunit.dev/docs/assertions/types): TUnit provides comprehensive assertions for testing types and type properties. These assertions work with both runtime values and `Type` objects th... - [AsyncTests](https://tunit.dev/docs/benchmarks/engine/AsyncTests): Performance benchmark results for AsyncTests - [Build Performance](https://tunit.dev/docs/benchmarks/engine/BuildTime): Compilation time benchmark results - [DataDrivenTests](https://tunit.dev/docs/benchmarks/engine/DataDrivenTests): Performance benchmark results for DataDrivenTests - [MassiveParallelTests](https://tunit.dev/docs/benchmarks/engine/MassiveParallelTests): Performance benchmark results for MassiveParallelTests - [MatrixTests](https://tunit.dev/docs/benchmarks/engine/MatrixTests): Performance benchmark results for MatrixTests - [ScaleTests](https://tunit.dev/docs/benchmarks/engine/ScaleTests): Performance benchmark results for ScaleTests - [SetupTeardownTests](https://tunit.dev/docs/benchmarks/engine/SetupTeardownTests): Performance benchmark results for SetupTeardownTests - [Performance Benchmarks](https://tunit.dev/docs/benchmarks/): Real-world performance comparisons between TUnit and other .NET testing frameworks - [Benchmark Methodology](https://tunit.dev/docs/benchmarks/methodology): How TUnit's performance benchmarks are measured and compared - [Mock Benchmark: Callback](https://tunit.dev/docs/benchmarks/mocks/Callback): Callback registration and execution — TUnit.Mocks vs Imposter vs Mockolate vs Moq vs NSubstitute vs FakeItEasy - [Mock Benchmark: CombinedWorkflow](https://tunit.dev/docs/benchmarks/mocks/CombinedWorkflow): Full workflow: create → setup → invoke → verify — TUnit.Mocks vs Imposter vs Mockolate vs Moq vs NSubstitute vs FakeItEasy - [Mock Benchmark: Invocation](https://tunit.dev/docs/benchmarks/mocks/Invocation): Calling methods on mock objects — TUnit.Mocks vs Imposter vs Mockolate vs Moq vs NSubstitute vs FakeItEasy - [Mock Benchmark: MockCreation](https://tunit.dev/docs/benchmarks/mocks/MockCreation): Mock instance creation performance — TUnit.Mocks vs Imposter vs Mockolate vs Moq vs NSubstitute vs FakeItEasy - [Mock Benchmark: Setup](https://tunit.dev/docs/benchmarks/mocks/Setup): Mock behavior configuration (returns, matchers) — TUnit.Mocks vs Imposter vs Mockolate vs Moq vs NSubstitute vs FakeItEasy - [Mock Benchmark: Verification](https://tunit.dev/docs/benchmarks/mocks/Verification): Verifying mock method calls — TUnit.Mocks vs Imposter vs Mockolate vs Moq vs NSubstitute vs FakeItEasy - [Mock Library Benchmarks](https://tunit.dev/docs/benchmarks/mocks/): Performance comparisons between TUnit.Mocks, Imposter, Mockolate, Moq, NSubstitute, FakeItEasy - [Attributes](https://tunit.dev/docs/comparison/attributes): Here are TUnit's equivalent attributes to other test frameworks. - [Framework Differences](https://tunit.dev/docs/comparison/framework-differences): TUnit is inspired by NUnit and xUnit — they're excellent frameworks that have served the .NET community well. TUnit was built to address some pain ... - [Aspire Integration Testing](https://tunit.dev/docs/examples/aspire): TUnit provides first-class support for [Aspire](https://aspire.dev/get-started/what-is-aspire/) integration testing through the `TUnit.Aspire` pack... - [ASP.NET Core Integration Testing](https://tunit.dev/docs/examples/aspnet): TUnit provides first-class support for ASP.NET Core integration testing through the `TUnit.AspNetCore` package. This package enables per-test isola... - [Complex Test Infrastructure Orchestration](https://tunit.dev/docs/examples/complex-test-infrastructure): TUnit provides a property injection system that can help orchestrate complex test infrastructure setups. This page demonstrates how TUnit handles t... - [File based C# application](https://tunit.dev/docs/examples/filebased-csharp): Starting with dotnet 10 (preview 4), you can use the new file-based C# application feature to run tests in a more straightforward way. - [FsCheck (Property-Based Testing)](https://tunit.dev/docs/examples/fscheck): [FsCheck](https://fscheck.github.io/FsCheck/) is a property-based testing framework for .NET. Property-based testing generates random test data to ... - [F# Interactive](https://tunit.dev/docs/examples/fsharp-interactive): F# Interactive (FSI) is a REPL (Read-Eval-Print Loop) for F#. It allows you to execute F# code interactively, making it a powerful tool for testing... - [Instrumenting: Global Test IDs](https://tunit.dev/docs/examples/instrumenting-global-test-ids): There are plenty use cases for having a unique identifier for each test in your test suite. If you're engineering tests that connect to a data sour... - [OpenTelemetry Tracing](https://tunit.dev/docs/examples/opentelemetry): TUnit emits `System.Diagnostics.Activity` trace spans at every level of the test lifecycle. When you configure an OpenTelemetry exporter (or any `A... - [Playwright](https://tunit.dev/docs/examples/playwright): There is a NuGet package to help with Playwright: `TUnit.Playwright` - [TUnit in CI/CD Pipelines](https://tunit.dev/docs/examples/tunit-ci-pipeline): When using TUnit in a CI/CD pipeline, you'll want to run tests, collect results, and publish reports for visibility. This guide provides complete, ... - [Cancelling a Test](https://tunit.dev/docs/execution/cancellation): Call `TestContext.Execution.Cancel()` to request cooperative cancellation of the current test without affecting other tests or the test session: - [CI/CD Reporting](https://tunit.dev/docs/execution/ci-cd-reporting): TUnit provides built-in integration with continuous integration and deployment platforms, automatically detecting and adapting to various CI enviro... - [Engine Modes](https://tunit.dev/docs/execution/engine-modes): TUnit supports two execution modes, providing flexibility for different development and deployment scenarios. - [Controlling Parallelism](https://tunit.dev/docs/execution/parallelism): TUnit runs all tests in parallel by default. This page covers three attributes that give you fine-grained control when you need it. - [Test Parameters](https://tunit.dev/docs/execution/parameters): TUnit allows you to pass custom key-value parameters to your tests at runtime using the `--test-parameter` command-line option. These parameters ar... - [Repeating](https://tunit.dev/docs/execution/repeating): If you want to repeat a test, add a `[Repeat]` attribute onto your test method or class. This takes an `int` of how many extra times the test shoul... - [Retrying](https://tunit.dev/docs/execution/retrying): Unfortunately sometimes our tests hit issues. It could be a blip on the network, but that could cause our entire test suite to fail which is frustr... - [Test Filters](https://tunit.dev/docs/execution/test-filters): Running TUnit via `dotnet run` supports test filters. - [Timeouts](https://tunit.dev/docs/execution/timeouts): If you want to stop a test after a specified amount of time, add a `[Timeout]` attribute onto your test method or class. This takes an `int` of how... - [Argument Formatters](https://tunit.dev/docs/extending/argument-formatters): When writing data-driven tests, especially with custom classes as arguments, the test explorer may only show the class name, making it hard to dist... - [Extensions](https://tunit.dev/docs/extending/built-in-extensions): As TUnit is built on top of Microsoft.Testing.Platform, it can tap into generic testing extension packages. - [Code Coverage](https://tunit.dev/docs/extending/code-coverage): TUnit includes built-in code coverage support via `Microsoft.Testing.Extensions.CodeCoverage`, which is automatically included when you install the... - [Data Source Generators](https://tunit.dev/docs/extending/data-source-generators): TUnit provides several base classes for creating custom data source generators: - [Display Names](https://tunit.dev/docs/extending/display-names): If you want simple control over the name of a test, you can use the `[DisplayName(...)]` attribute. - [Dynamically Created Tests](https://tunit.dev/docs/extending/dynamic-tests): TUnit offers the ability to create your tests via dynamic code, as opposed to the standard `[Test]` attribute and data attributes. - [Exception Handling](https://tunit.dev/docs/extending/exception-handling): When a test fails, TUnit throws an exception. Most of the time you don't need to think about this — the framework handles it and reports the failur... - [Extension Points](https://tunit.dev/docs/extending/extension-points): TUnit provides several extension points that allow you to customize and extend the framework's behavior. These interfaces enable you to implement c... - [Libraries](https://tunit.dev/docs/extending/libraries): When building a reusable library that defines shared hooks, custom attributes, base classes, or data sources for TUnit, reference **`TUnit.Core`** ... - [Logging](https://tunit.dev/docs/extending/logging): TUnit provides a flexible logging system that captures all test output and routes it to configurable destinations called "log sinks". - [Installing TUnit](https://tunit.dev/docs/getting-started/installation): Assuming you have the .NET SDK installed, run: - [Running your tests](https://tunit.dev/docs/getting-started/running-your-tests): As TUnit is built on-top of the newer Microsoft.Testing.Platform, and combined with the fact that TUnit tests are source generated, running your te... - [Writing your first test](https://tunit.dev/docs/getting-started/writing-your-first-test): Here's a complete TUnit test class with all necessary using statements: - [Tips & Pitfalls](https://tunit.dev/docs/guides/best-practices): TUnit-specific tips to avoid common mistakes. - [Distributed Tracing](https://tunit.dev/docs/guides/distributed-tracing): This page is for users wiring TUnit up to a tracing backend like Seq, Jaeger, Tempo, or the Aspire dashboard. If you just want a working setup, sta... - [HTML Test Report](https://tunit.dev/docs/guides/html-report): TUnit automatically generates a rich HTML test report after every test run. No configuration is needed — the report is always on by default. - [Performance Best Practices](https://tunit.dev/docs/guides/performance): This guide provides recommendations for optimizing test performance and ensuring your TUnit test suite runs efficiently. - [Philosophy](https://tunit.dev/docs/guides/philosophy): TUnit does some things differently from other .NET testing frameworks. This page explains the thinking behind those choices. - [Aggregated Reports (Multiple Test Projects)](https://tunit.dev/docs/guides/report-aggregation): When you run several test projects with a single command — `dotnet test` on a solution, or one `dotnet run` per microservice test suite — each proj... - [Intro](https://tunit.dev/docs/intro): **TUnit** is another testing framework for C# / .NET. - [Migrating from MSTest](https://tunit.dev/docs/migration/mstest): :::from-mstest Performance Boost - [Migrating from NUnit](https://tunit.dev/docs/migration/nunit): :::from-nunit Performance Boost - [TestContext Interface Organization Migration Guide](https://tunit.dev/docs/migration/testcontext-interface-organization): TUnit has reorganized the `TestContext` API to provide a cleaner, more discoverable interface structure. Properties and methods are now organized i... - [Migrating from xUnit.net](https://tunit.dev/docs/migration/xunit): :::from-xunit Performance Boost - [Command Line Flags](https://tunit.dev/docs/reference/command-line-flags): :::info - [Environment Variables](https://tunit.dev/docs/reference/environment-variables): TUnit supports configuration through environment variables, allowing you to set defaults without modifying command-line arguments. This is particul... - [Programmatic Configuration](https://tunit.dev/docs/reference/programmatic-configuration): The `context.Settings` API lets you configure TUnit settings directly in code. This is useful when you want discoverable, version-controlled defaul... - [Test Configuration](https://tunit.dev/docs/reference/test-configuration): TUnit supports having a `testconfig.json` file within your test project. - [Troubleshooting & FAQ](https://tunit.dev/docs/troubleshooting): Assertions don't execute until awaited — forgetting `await` means the test passes silently. See [Awaiting Assertions](assertions/awaiting.md) for d... - [AOT Compatibility and Generic Tests](https://tunit.dev/docs/writing-tests/aot): TUnit's source generation mode provides compile-time safety and performance benefits, but requires specific patterns for advanced scenarios like ge... - [Data Driven Tests](https://tunit.dev/docs/writing-tests/arguments): Inject compile-time known data via `[Arguments(...)]` attributes. The attribute takes an array of arguments that must match the test method's param... - [Test Artifacts](https://tunit.dev/docs/writing-tests/artifacts): Test artifacts are files (screenshots, logs, videos, JSON dumps, etc.) that you can attach to your tests. They are invaluable for debugging test fa... - [Injectable Class Data Source](https://tunit.dev/docs/writing-tests/class-data-source): The `ClassDataSource` attribute is used to instantiate and inject in new classes as parameters to your tests and/or test classes. - [CombinedDataSources](https://tunit.dev/docs/writing-tests/combined-data-source): The `[CombinedDataSources]` attribute enables you to apply different data source attributes to individual parameters, creating test cases through C... - [Culture](https://tunit.dev/docs/writing-tests/culture): The `[Culture]` attribute sets the [current Culture](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.cultureinfo.currentculture) ... - [Choosing a Data Approach](https://tunit.dev/docs/writing-tests/data-driven-overview): TUnit offers several ways to provide data to your tests. Use this guide to pick the right one. - [Deferring Data Source Enumeration](https://tunit.dev/docs/writing-tests/defer-enumeration): By default, data sources are enumerated during **test discovery** — every row becomes its own test node, so a data source that produces thousands o... - [Dependency Injection](https://tunit.dev/docs/writing-tests/dependency-injection): TUnit provides two mechanisms for controlling how test classes are constructed: the low-level `IClassConstructor` interface and the higher-level `D... - [Event Subscribing](https://tunit.dev/docs/writing-tests/event-subscribing): Objects associated with your tests have the ability to subscribe to lifecycle events generated by TUnit. - [Explicit](https://tunit.dev/docs/writing-tests/explicit): If you want a test to only be run explicitly (and not part of all general tests) then you can add the `[Explicit]` attribute. - [Generic Attributes](https://tunit.dev/docs/writing-tests/generic-attributes): TUnit provides generic versions of several attributes that offer enhanced type safety and better IDE support. These attributes allow you to specify... - [Hooks](https://tunit.dev/docs/writing-tests/hooks): Hooks let you run code at specific points in the test lifecycle using `[Before]` / `[BeforeEvery]` and `[After]` / `[AfterEvery]` attributes. Most ... - [Test Lifecycle Overview](https://tunit.dev/docs/writing-tests/lifecycle): TUnit provides multiple mechanisms for hooking into the test lifecycle: - [Matrix Tests](https://tunit.dev/docs/writing-tests/matrix-tests): The Matrix data source is a way to specify different arguments per parameter, and then generate every possible combination of all of those arguments. - [Method Data Sources](https://tunit.dev/docs/writing-tests/method-data-source): A limitation of passing data in with `[Arguments(...)]` is that the data must be `constant` values. For example, we can't new up an object and pass... - [Advanced Features](https://tunit.dev/docs/writing-tests/mocking/advanced): If the mocked interface declares events, TUnit.Mocks generates `Raise{EventName}()` extension methods directly on `Mock`: - [Argument Matchers](https://tunit.dev/docs/writing-tests/mocking/argument-matchers): Argument matchers control which calls a setup or verification matches. The same matchers work in both contexts — the chain method determines whethe... - [HTTP Mocking](https://tunit.dev/docs/writing-tests/mocking/http): `TUnit.Mocks.Http` provides `MockHttpHandler` — a drop-in `HttpMessageHandler` replacement for testing code that uses `HttpClient`. - [TUnit.Mocks](https://tunit.dev/docs/writing-tests/mocking/): TUnit.Mocks is a **source-generated, AOT-compatible** mocking framework. Because mocks are generated at compile time, it works with Native AOT, tri... - [Logging](https://tunit.dev/docs/writing-tests/mocking/logging): `TUnit.Mocks.Logging` provides `MockLogger` — a simple `ILogger` implementation that captures log entries for inspection and verification. - [Setup & Stubbing](https://tunit.dev/docs/writing-tests/mocking/setup): Methods are called directly on `Mock` — the chain method (`.Returns()`, `.Throws()`, etc.) makes it a setup. - [Verification](https://tunit.dev/docs/writing-tests/mocking/verification): Verification uses the same methods as setup — the chain method (`.WasCalled()`, `.WasNeverCalled()`) makes it a verification instead of a setup. - [Nested Data Sources with Initialization](https://tunit.dev/docs/writing-tests/nested-data-sources): When writing integration tests, you often need complex test fixtures that depend on other initialized resources. TUnit's nested data source initial... - [Test Ordering & Dependencies](https://tunit.dev/docs/writing-tests/ordering): :::warning - [Property Injection](https://tunit.dev/docs/writing-tests/property-injection): TUnit's AOT-compatible property injection system makes it easy to initialize properties on your test class with compile-time safety and excellent p... - [Skipping Tests](https://tunit.dev/docs/writing-tests/skip): If you want to simply skip a test, just place a `[Skip(reason)]` attribute on your test with an explanation of why you're skipping it. - [Test Context](https://tunit.dev/docs/writing-tests/test-context): All tests have a `TestContext` object available to them. - [Test Data Row Metadata](https://tunit.dev/docs/writing-tests/test-data-row): When using data sources like `[MethodDataSource]` or `[ClassDataSource]`, you may want to customize individual test cases with specific display nam... - [Things to know](https://tunit.dev/docs/writing-tests/things-to-know): TUnit has made some decisions by design. You may need to know about them: