Skip to content
Development
Skill

/tunit

Write, run, or repair .NET tests that use TUnit. Use when a repo uses `TUnit`, `TUnit.Playwright`, `[Test]`, `[Arguments]`, `ClassDataSource`, `SharedType.PerTestSession`, or Microsoft.Testing.Platform-based execution. Preserve TUnit's parallel-by-default model and constrain

From plugin
dotnet-skills
499200 skills17 agents

Claude Code

$ npx -y skills add managedcode/dotnet-skills --skill tunit --agent claude-code

SKILL.md

tunit.SKILL.md
name: tunit
description: "Write, run, or repair .NET tests that use TUnit. Use when a repo uses `TUnit`, `TUnit.Playwright`, `[Test]`, `[Arguments]`, `ClassDataSource`, `SharedType.PerTestSession`, or Microsoft.Testing.Platform-based execution. Preserve TUnit's parallel-by-default model and constrain only destructive shared-state collisions. DO NOT USE FOR: xUnit projects; MSTest projects."

TUnit

Trigger On

  • the repo uses TUnit
  • you need to add, run, debug, or repair TUnit tests
  • the repo uses Microsoft.Testing.Platform-based test execution
  • the repo uses `ClassDataSource<...>(Shared = SharedType.PerTestSession)`, `TUnit.Playwright`, or `--treenode-filter`

Do Not Use For

  • xUnit projects
  • MSTest projects
  • generic test strategy with no TUnit-specific mechanics

Inputs

  • the nearest `AGENTS.md`
  • the test project file and package references
  • the repo's current TUnit execution command

Workflow

1. Confirm the project really uses TUnit and not a different MTP-based framework. 2. Read the repo's real `test` command from `AGENTS.md`. If the repo has no explicit command yet, start with `dotnet test PROJECT_OR_SOLUTION`. 3. Keep the TUnit execution model intact:

  • tests are source-generated at build time
  • tests run in parallel by default
  • on .NET 10, test modules also run in parallel by default up to `Environment.ProcessorCount`
  • built-in analyzers should remain enabled

4. Choose the fixture level deliberately:

  • plain TUnit tests for isolated logic
  • shared AppHost/Aspire fixtures for HTTP, SignalR, SSE, or UI flows
  • `WebApplicationFactory` layered over shared Aspire infra when tests need Host DI services, `IGrainFactory`, or other runtime internals

5. Reuse expensive fixtures with `ClassDataSource<Fixture>(Shared = SharedType.PerTestSession)` instead of booting distributed infrastructure per test. Fixture reuse does not serialize consumers: keep the fixture concurrency-safe and give each test unique mutable state. 6. Keep tests and test modules parallel. Do not add `--max-parallel-test-modules 1`, `TUNIT_MAX_PARALLEL_TESTS=1`, `[assembly: NotInParallel]`, a class-wide `[NotInParallel]`, or an equivalent global restriction. 7. Use keyed `[NotInParallel("collision-domain")]` only on the smallest tests that perform destructive changes to the same shared state and can corrupt one another. A shared read-only fixture, expensive startup, module boundary, or vague CI-stability concern is not a reason to limit parallelism. 8. Run the narrowest useful scope first with `dotnet test ... --treenode-filter "..."` on .NET 10. Use the older `--` separator only when the repository is pinned to an SDK that requires it. 9. Follow `Test Output Budget`: show bounded root-error evidence and link coverage, Playwright screenshots, and HTML artifacts; never dump host logs. 10. Use `[Test]`, `[Arguments]`, hooks, and dependencies only when they make the scenario clearer, not because the framework allows it.

Test Output Budget

  • Keep native runner progress and ANSI enabled (`--progress on --ansi on` for supported MTP/TUnit runners); use a PTY locally. Do not replay progress redraws into model context. Use the detected runner's flags, not MTP switches on VSTest.
  • Show warnings and errors plus one final summary (counts, duration, exit code). Configure test-owned console logging at `Warning`; keep Information/Debug/Trace, successful-test output, and expected negative-test noise out of context. Quiet build verbosity alone does not filter application logs.
  • On failure, crash, startup error, or timeout, show the failing test/resource, root exception, and relevant stack frames. Deduplicate; cap each diagnostic tool response at 80 lines / 8 KiB, whichever comes first. Never automatically dump stdout/stderr, host logs, browser console history, DOM/HTML, TRX, or crash artifacts.
  • Keep necessary diagnostics in size-bounded or rotating artifacts and link them. Search by exact failure/correlation; read bounded excerpts, never whole logs. Capture/filter noisy output before tool delivery, preserve the real exit code, and disclose truncation. Monitor actual activity; silence alone does not prove a hang.

Bootstrap When Missing

If `TUnit` is requested but not configured yet:

1. Detect current state:

  • `rg -n "TUnit|Microsoft\\.Testing\\.Platform" -g '*.csproj' -g 'Directory.Build.*' .`

2. Add the minimal package set to the test project:

  • `dotnet add TEST_PROJECT.csproj package TUnit`
  • do not add `Microsoft.NET.Test.Sdk` to a current TUnit project; it selects the VSTest path and conflicts with the normal Microsoft.Testing.Platform setup

3. Keep the runner model explicit in `AGENTS.md` and CI:

  • record that the repo uses Microsoft.Testing.Platform-compatible execution for this test project
  • record the exact `dotnet test TEST_PROJECT.csproj` command the repo will use

4. Add one small executable test using `[Test]`. 5. Run `dotnet test TEST_PROJECT.csproj` and return `status: configured` or `status: improved`. 6. If the repo intentionally standardizes on xUnit or MSTest, return `status: not_applicable` unless migration is explicitly requested.

Deliver

  • TUnit tests that respect source generation and parallel execution
  • commands that work in local and CI runs
  • framework-specific verification guidance for the repo
  • a fixture strategy that matches the actual test scope: logic-only, AppHost/API, Host DI/grains, or Playwright UI

Validate

  • the command matches the repo's TUnit runner style
  • focused runs use `--treenode-filter` rather than VSTest-style `--filter`
  • .NET 10 runs pass MTP options directly without a `--` separator
  • no global or assembly-wide single-thread setting has been introduced
  • any keyed non-parallel group is limited to tests with a named destructive shared-state collision
  • shared distributed fixtures use `SharedType.PerTestSession` or an equivalent reuse pattern
  • fixture and shared infrastructure are safe for concurren
Read more
@managedcode
Ships withdotnet-skills

Stop explaining .NET to your AI. Start building. We've all been there: asking Claude to use Entity Framework, only to get EF6 patterns in a .NET 8 project. Explaining to Copilot that Blazor Server and Blazor WebAssembly aren't the same thing.

499200 skills17 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
499
Star history of managedcode/dotnet-skills on GitHub, a chart by star-history.com

Other skills on dotnet-skills.

aspnet-core

aspnet-core

Build, debug, modernize, or review ASP.NET Core applications with correct hosting, middleware, security, configuration, logging,…

aspire

aspire

Build, upgrade, and operate Aspire 13.5.x C# or TypeScript application hosts with the current CLI, AppHost, ServiceDefaults,…

avalonia

avalonia

Build and debug Avalonia 11/12 .NET applications with XAML, compiled bindings, MVVM, custom controls, desktop lifetimes, and…

azure-functions

azure-functions

Build, review, or migrate Azure Functions in .NET with correct execution model, isolated worker setup, bindings, DI, and Durable…

blazor

blazor

Build and review Blazor applications across server, WebAssembly, web app, and hybrid scenarios with correct component design,…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about tunit.

Which coding agents can use tunit?
tunit installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.