TU
tunit
Use this skill to write, review, and fix TUnit tests in .NET projects: for new test classes, assertions, data-driven tests, lifecycle hooks, debugging, migrating from xUnit/NUnit, choosing assertions, using Bogus, NSubstitute mocks, integration tests, or questions about parallelism and test ordering
Install
mkdir -p .claude/skills/tunit && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/13421" && unzip -o skill.zip -d .claude/skills/tunit && rm skill.zipInstalls to .claude/skills/tunit
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Use this skill to write, review, and fix TUnit tests in .NET projects: for new test classes, assertions, data-driven tests, lifecycle hooks, debugging, migrating from xUnit/NUnit, choosing assertions, using Bogus, NSubstitute mocks, integration tests, or questions about parallelism and test ordering; prefer this skill over guessing, as TUnit's async-first API has non-obvious patterns differing from xUnit/NUnit.414 charsno explicit “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
About this skill
TUnit Testing Skill
TUnit is a modern .NET testing framework that is async-first, source-generated, and runs on Microsoft.Testing.Platform.
Quick-start anatomy
public class OrderHandlerTests
{
[Test]
[Category("Unit")] // categorise for filtering
public async Task PlaceOrder_Valid_ReturnsOk()
{
// Arrange …
// Act …
// Assert — always await the assertion
await Assert.That(result).IsNotNull();
await Assert.That(result.Status).IsEqualTo("Confirmed");
}
}
Key rule: every assertion line must be await-ed. Forgetting the await
silently skips the assertion.
Reference files — read before writing code
| Topic | File |
|---|---|
| Assertion API (equality, nulls, booleans, collections, strings, exceptions, multiple) | references/assertions.md |
| All attributes (Test, Category, Arguments, Before/After, Retry, Repeat, NotInParallel…) | references/attributes.md |
| Data-driven tests (Arguments, MethodDataSource, ClassDataSource) | references/data-driven.md |
| Integration test patterns (Aspire, test infrastructure, async helpers) | references/integration-patterns.md |
Core rules
✅ [Test] async Task ❌ [Fact] / [TestMethod] / [TestCase]
✅ await Assert.That(...) ❌ Assert.Equal / FluentAssertions
✅ Per-test data creation ❌ shared mutable state between tests
Running tests
dotnet test # all projects (parallel)
dotnet test -- --maximum-parallel-tests 4 # cap parallelism
dotnet test -- --treenode-filter "/*/*/*/*[Category=Unit]" # filter by category
dotnet test --project tests/MyProject.Tests/MyProject.Tests.csproj
Common mistakes & fixes
| Mistake | Fix |
|---|---|
| Assertion silently skipped | Add await to every Assert.That(…) call |
| Tests interfere with each other | Create all test data inside each test; never share mutable fields |
| Polling for eventual consistency | Use condition helpers or WaitForConditionAsync patterns; never Task.Delay |
Assert.Fail not reached after exception | Use Assert.That(…).Throws<T>() pattern instead of try/catch |
Missing [Before(Class)] / [After(Class)] | Hooks must be public static async Task; see attributes reference |
| Data-driven test parameters don't compile | Types in [Arguments] must exactly match method parameter types |