Skip to main content

Installing TUnit

Easily​

Assuming you have the .NET SDK installed, simply run:

dotnet new install TUnit.Templates

dotnet new TUnit -n "YourProjectName"

A new test project will be created for you with some samples of different test types and tips. When you're ready to get going, delete them and create your own!

Manually​

First create an empty .NET console application:

dotnet new console --name YourTestProjectNameHere

To that project add the TUnit package:

cd YourTestProjectNameHere
dotnet add package TUnit --prerelease

And then remove any automatically generated Program.cs or main method, as this'll be taken care of by the TUnit package.

Global Usings​

The TUnit package automatically configures global usings for common TUnit namespaces, so your test files don't need to include using statements for:

  • TUnit.Core (for [Test] attribute)
  • TUnit.Assertions (for Assert.That())
  • TUnit.Assertions.Extensions (for assertion methods)

This means your test files can be as simple as:

namespace MyTests;

public class MyTests // No [TestClass] needed!
{
[Test] // Available without explicit using statement
public async Task MyTest()
{
await Assert.That(true).IsTrue(); // Assert is available automatically
}
}

What's Included in the TUnit Package​

When you install the TUnit meta package, you automatically get several useful extensions without any additional installation:

✅ Built-In Extensions​

Microsoft.Testing.Extensions.CodeCoverage

  • 📊 Code coverage support via --coverage flag
  • 📈 Outputs Cobertura and XML formats
  • 🔄 Replacement for Coverlet (which is not compatible with TUnit)

Microsoft.Testing.Extensions.TrxReport

  • 📝 TRX test report generation via --report-trx flag
  • 🤝 Compatible with Azure DevOps and other CI/CD systems

This means you can run tests with coverage and reports right away:

# Run tests with code coverage
dotnet run --configuration Release --coverage

# Run tests with TRX report
dotnet run --configuration Release --report-trx

# Both coverage and report
dotnet run --configuration Release --coverage --report-trx

Important: Do not install coverlet.collector or coverlet.msbuild. These packages are incompatible with TUnit because they require the VSTest platform, while TUnit uses the modern Microsoft.Testing.Platform.

For more details, see:

That's it. We're ready to write our first test.

Your .csproj should be as simple as something like:

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="TUnit" Version="*" />
</ItemGroup>

</Project>
danger

If you're used to other testing frameworks, you're probably used to the package Microsoft.NET.Test.Sdk. This should NOT be used with TUnit. It'll stop test discovery from working properly.

.NET Framework​

If you are still targeting .NET Framework, TUnit will try to Polyfill some missing types that are used by the compiler, such as the ModuleInitialiserAttribute.

If you have issues with other Polyfill libraries also defining them, in your project files, you can define the property <EnableTUnitPolyfills>false</EnableTUnitPolyfills> to stop TUnit generating them for you.

Central Package Management (CPM)​

TUnit is fully compatible with NuGet Central Package Management. When CPM is enabled (via Directory.Packages.props), TUnit will automatically inject the Polyfill package using VersionOverride, so you don't need to manually add it to your Directory.Packages.props file.

If you prefer to manage the Polyfill version yourself, you can:

  • Add <PackageVersion Include="Polyfill" Version="x.x.x" /> to your Directory.Packages.props, OR
  • Disable automatic injection with <EnableTUnitPolyfills>false</EnableTUnitPolyfills> and add it manually

Embedded Polyfill Attributes​

TUnit automatically sets <PolyUseEmbeddedAttribute>true</PolyUseEmbeddedAttribute> to ensure that Polyfill types are embedded in each project. This prevents type conflicts when using InternalsVisibleTo or when multiple projects in your solution reference Polyfill. Each project gets its own isolated copy of the polyfill types, following the recommended Polyfill consuming pattern.

You can override this behavior by setting <PolyUseEmbeddedAttribute>false</PolyUseEmbeddedAttribute> in your project file if needed.