New to Claude Skills? Learn how to install them →

github on GitHub

TUnit Best Practices

OfficialFree

Master TUnit unit testing with best practices and data-driven tests.

by github37.7k stars on github/awesome-copilot
5 views
Updated Aug 10, 2026
Get this skill

Free · Opens the source repo

What TUnit Best Practices does

TUnit Best Practices is designed to guide developers in writing effective unit tests using TUnit, a modern testing framework for .NET. This skill covers both standard and data-driven testing approaches, ensuring that users can implement robust testing strategies in their projects. By following the outlined best practices, developers can enhance the reliability of their code and streamline their testing processes.

The skill emphasizes the importance of structuring tests correctly, using naming conventions, and leveraging TUnit's features such as lifecycle hooks and fluent assertions. It provides clear instructions on setting up a separate test project, creating test classes that correspond to the classes being tested, and utilizing the .NET SDK commands for running tests. This structured approach not only facilitates the writing of effective tests but also promotes maintainability and clarity in the test codebase.

Additionally, TUnit Best Practices delves into advanced features such as data-driven testing, allowing developers to create tests with various input data efficiently. The skill explains how to use attributes like [Arguments], [MethodData], and [ClassData] to implement data-driven tests, making it easier to validate multiple scenarios without duplicating test code. This is particularly beneficial for complex applications where testing a wide range of inputs is crucial for ensuring software quality.

Overall, TUnit Best Practices is an essential resource for .NET developers looking to adopt or improve their unit testing practices with TUnit. By following the guidelines provided, users can create comprehensive test suites that enhance code quality and facilitate easier debugging and maintenance.

When to use it

Use this skill when starting a new project with TUnit or when migrating from another testing framework like xUnit.

When not to use it

This skill may not be suitable for projects that do not utilize TUnit or for teams that prefer a different testing framework with its own conventions.

What you can build with it

Setting Up a New TUnit Project

Follow the guidelines to create a structured test project that adheres to TUnit best practices.

Implementing Data-Driven Testing

Utilize TUnit's data-driven testing features to efficiently validate multiple scenarios with minimal code duplication.

Migrating from xUnit to TUnit

Use the provided migration instructions to transition your existing tests from xUnit to TUnit seamlessly.

How to install TUnit Best Practices

View source

1. Install with the skills CLI

npx skills add github/awesome-copilot/csharp-tunit --agent claude-code

2. Or install it manually

Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.

Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs

Inside SKILL.md

Written by github

TUnit Best Practices

Your goal is to help me write effective unit tests with TUnit, covering both standard and data-driven testing approaches.

Project Setup

  • Use a separate test project with naming convention [ProjectName].Tests
  • Reference TUnit package and TUnit.Assertions for fluent assertions
  • Create test classes that match the classes being tested (e.g., CalculatorTests for Calculator)
  • Use .NET SDK test commands: dotnet test for running tests
  • TUnit requires .NET 8.0 or higher

Test Structure

  • No test class attributes required (like xUnit/NUnit)
  • Use [Test] attribute for test methods (not [Fact] like xUnit)
  • Follow the Arrange-Act-Assert (AAA) pattern
  • Name tests using the pattern MethodName_Scenario_ExpectedBehavior
  • Use lifecycle hooks: [Before(Test)] for setup and [After(Test)] for teardown
  • Use [Before(Class)] and [After(Class)] for shared context between tests in a class
  • Use [Before(Assembly)] and [After(Assembly)] for shared context across test classes
  • TUnit supports advanced lifecycle hooks like [Before(TestSession)] and [After(TestSession)]

Standard Tests

  • Keep tests focused on a single behavior
  • Avoid testing multiple behaviors in one test method
  • Use TUnit's fluent assertion syntax with await Assert.That()
  • Include only the assertions needed to verify the test case
  • Make tests independent and idempotent (can run in any order)
  • Avoid test interdependencies (use [DependsOn] attribute if needed)

Data-Driven Tests

  • Use [Arguments] attribute for inline test data (equivalent to xUnit's [InlineData])
  • Use [MethodData] for method-based test data (equivalent to xUnit's [MemberData])
  • Use [ClassData] for class-based test data
  • Create custom data sources by implementing ITestDataSource
  • Use meaningful parameter names in data-driven tests
  • Multiple [Arguments] attributes can be applied to the same test method

Assertions

  • Use await Assert.That(value).IsEqualTo(expected) for value equality
  • Use await Assert.That(value).IsSameReferenceAs(expected) for reference equality
  • Use await Assert.That(value).IsTrue() or await Assert.That(value).IsFalse() for boolean conditions
  • Use await Assert.That(collection).Contains(item) or await Assert.That(collection).DoesNotContain(item) for collections
  • Use await Assert.That(value).Matches(pattern) for regex pattern matching
  • Use await Assert.That(action).Throws<TException>() or await Assert.That(asyncAction).ThrowsAsync<TException>() to test exceptions
  • Chain assertions with .And operator: await Assert.That(value).IsNotNull().And.IsEqualTo(expected)
  • Use .Or operator for alternative conditions: await Assert.That(value).IsEqualTo(1).Or.IsEqualTo(2)
  • Use .Within(tolerance) for DateTime and numeric comparisons with tolerance
  • All assertions are asynchronous and must be awaited

Advanced Features

  • Use [Repeat(n)] to repeat tests multiple times
  • Use [Retry(n)] for automatic retry on failure
  • Use [ParallelLimit<T>] to control parallel execution limits
  • Use [Skip("reason")] to skip tests conditionally
  • Use [DependsOn(nameof(OtherTest))] to create test dependencies
  • Use [Timeout(milliseconds)] to set test timeouts
  • Create custom attributes by extending TUnit's base attributes

Test Organization

  • Group tests by feature or component
  • Use [Category("CategoryName")] for test categorization
  • Use [DisplayName("Custom Test Name")] for custom test names
  • Consider using TestContext for test diagnostics and information
  • Use conditional attributes like custom [WindowsOnly] for platform-specific tests

Performance and Parallel Execution

  • TUnit runs tests in parallel by default (unlike xUnit which requires explicit configuration)
  • Use [NotInParallel] to disable parallel execution for specific tests
  • Use [ParallelLimit<T>] with custom limit classes to control concurrency
  • Tests within the same class run sequentially by default
  • Use [Repeat(n)] with [ParallelLimit<T>] for load testing scenarios

Migration from xUnit

  • Replace [Fact] with [Test]
  • Replace [Theory] with [Test] and use [Arguments] for data
  • Replace [InlineData] with [Arguments]
  • Replace [MemberData] with [MethodData]
  • Replace Assert.Equal with await Assert.That(actual).IsEqualTo(expected)
  • Replace Assert.True with await Assert.That(condition).IsTrue()
  • Replace Assert.Throws<T> with await Assert.That(action).Throws<T>()
  • Replace constructor/IDisposable with [Before(Test)]/[After(Test)]
  • Replace IClassFixture<T> with [Before(Class)]/[After(Class)]

Why TUnit over xUnit?

TUnit offers a modern, fast, and flexible testing experience with advanced features not present in xUnit, such as asynchronous assertions, more refined lifecycle hooks, and improved data-driven testing capabilities. TUnit's fluent assertions provide clearer and more expressive test validation, making it especially suitable for complex .NET projects.

Frequently asked questions about TUnit Best Practices

Similar skills