Agent Skills
› managedcode/dotnet-skills
› tunit
tunit
GitHub指导 .NET 项目中 TUnit 测试的编写、运行与修复。适用于使用 TUnit 或 Microsoft.Testing.Platform 的项目,强调保持并行执行模型,避免用于 xUnit/MSTest。
Trigger Scenarios
项目使用 TUnit
需要添加、运行或调试 TUnit 测试
使用 Microsoft.Testing.Platform 执行测试
Install
npx skills add managedcode/dotnet-skills --skill tunit -g -y
SKILL.md
Frontmatter
{
"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
- Confirm the project really uses TUnit and not a different MTP-based framework.
- Read the repo's real
testcommand fromAGENTS.md. If the repo has no explicit command yet, start withdotnet test PROJECT_OR_SOLUTION. - 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
- Choose the fixture level deliberately:
- plain TUnit tests for isolated logic
- shared AppHost/Aspire fixtures for HTTP, SignalR, SSE, or UI flows
WebApplicationFactorylayered over shared Aspire infra when tests need Host DI services,IGrainFactory, or other runtime internals
- 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. - 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. - 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. - 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. - Capture useful failure evidence: host log dumps, focused console output, coverage files, and Playwright screenshots/HTML for UI tests.
- Use
[Test],[Arguments], hooks, and dependencies only when they make the scenario clearer, not because the framework allows it.
Bootstrap When Missing
If TUnit is requested but not configured yet:
- Detect current state:
rg -n "TUnit|Microsoft\\.Testing\\.Platform" -g '*.csproj' -g 'Directory.Build.*' .
- Add the minimal package set to the test project:
dotnet add TEST_PROJECT.csproj package TUnit- do not add
Microsoft.NET.Test.Sdkto a current TUnit project; it selects the VSTest path and conflicts with the normal Microsoft.Testing.Platform setup
- Keep the runner model explicit in
AGENTS.mdand CI:- record that the repo uses Microsoft.Testing.Platform-compatible execution for this test project
- record the exact
dotnet test TEST_PROJECT.csprojcommand the repo will use
- Add one small executable test using
[Test]. - Run
dotnet test TEST_PROJECT.csprojand returnstatus: configuredorstatus: improved. - If the repo intentionally standardizes on xUnit or MSTest, return
status: not_applicableunless 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-filterrather 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.PerTestSessionor an equivalent reuse pattern - fixture and shared infrastructure are safe for concurrent consumers; mutable data is isolated per test
- built-in TUnit analyzers remain active
- coverage tooling matches Microsoft.Testing.Platform if coverage is enabled
- UI failures capture artifacts and server-side failures expose enough logs to avoid blind reruns
Test Harness
flowchart LR
A["TUnit task"] --> B{"What does the test need?"}
B -->|"Single component only"| C["Plain TUnit test"]
B -->|"HTTP / SignalR / resource graph"| D["Shared Aspire/AppHost fixture"]
B -->|"Host DI / grains / runtime services"| E["Shared Aspire/AppHost fixture + WebApplicationFactory"]
B -->|"Browser automation"| F["Shared Aspire/AppHost fixture + Playwright"]
C & D & E & F --> G["Run focused with --treenode-filter"]
G --> H["Capture logs, artifacts, and coverage"]
Load References
- references/patterns.md
- references/migration.md
- references/tunit.md
- references/integration-testing.md
Running Tests
TUnit uses Microsoft.Testing.Platform. Use --treenode-filter for filtering, not VSTest --filter. On .NET 10, pass MTP switches directly; older SDKs may require --.
# Run all tests
dotnet test --solution MySolution.sln
# Run one test project
dotnet test --project tests/MyProject.Tests/MyProject.Tests.csproj
# Filter by class
dotnet test --project tests/MyProject.Tests/MyProject.Tests.csproj --treenode-filter "/*/*/CalculatorTests/*"
# Filter by category
dotnet test --project tests/MyProject.Tests/MyProject.Tests.csproj --treenode-filter "/*/*/*/*[Category=Integration]"
# Coverage on Microsoft.Testing.Platform
dotnet test --solution MySolution.sln --coverage --coverage-output coverage.cobertura.xml --coverage-output-format cobertura
# Raw runner help when the repo needs direct TUnit app switches
dotnet run --project tests/MyProject.Tests/MyProject.Tests.csproj -- --help
Filter syntax: /<Assembly>/<Namespace>/<Class>/<Test> with * wildcards. See references/patterns.md for full examples.
Example Requests
- "Run this TUnit project correctly."
- "Fix our TUnit CI command."
- "Add a regression test in TUnit without breaking parallelism."
Version History
-
6cd8621
Current 2026-09-03 08:01
刷新上游配置并优化并行测试指南,移除旧版并行限制器说明。
- 7ab7f03 2026-07-25 05:26


