Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Recommend or run the exact `dotnet test` command. ALWAYS use when the user asks to run, filter, or troubleshoot .NET tests or wants the precise command, flags, or argument order — the right syntax depends on the test platform (VSTest vs Microsoft.Testing.Platform) and SDK version and is easy to get wrong from memory. USE FOR: running all tests or a subset (a specific class, category, or trait) via filters; a single framework in a multi-TFM project (`--framework`); TRX reports; crash or hang dump
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-07 | ✗→✓ | ▲ Improved | 255% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 160% | 0% |
| case-16 | ✗→✓ | ▲ Improved | 200% | 0% |
| case-17 | ✗→✓ | ▲ Improved | 172% | 0% |
| case-19 | ✗→✓ | ▲ Improved | 142% | 0% |
Detect the test platform and framework, run tests, and apply filters using dotnet test.
writing-mstest-tests for MSTest, or general coding assistance for other frameworks)migrate-vstest-to-mtp)mtp-hot-reload)| Input | Required | Description | |-------|----------|-------------| | Project or solution path | No | Path to the test project (.csproj) or solution (.sln, .slnf, .slnx). Defaults to current directory. | | Filter expression | No | Filter expression to select specific tests | | Target framework | No | Target framework moniker to run against (e.g., net8.0) |
These are the most common agent mistakes. Internalize before proceeding:
| Rule | Why | |------|-----| | Do NOT use --logger trx for MTP projects | MTP uses --report-trx (requires the TrxReport extension package) | | Do NOT use --report-trx for VSTest projects | VSTest uses --logger trx | | Do NOT use -- --arg on .NET SDK 10+ | SDK 10+ passes MTP args directly: dotnet test --project . --report-trx | | Do NOT omit -- on .NET SDK 8/9 with MTP | SDK 8/9 requires the separator: dotnet test -- --report-trx | | Do NOT use --filter "ClassName=..." with xUnit v3 on MTP | xUnit v3 on MTP uses --filter-class, --filter-method, --filter-trait | | Do NOT use bare positional path on SDK 10+ | Use --project <path> or --solution <path> instead | | Do NOT use --blame for MTP projects | MTP uses --blame-crash and --blame-hang-timeout separately (each requires its extension package) | | Do NOT use --collect "Code Coverage" for MTP | MTP uses --coverage (requires the CodeCoverage extension package) |
| Platform | SDK | Command pattern | |----------|-----|----------------| | VSTest | Any | dotnet test [<path>] [--filter <expr>] [--logger trx] | | MTP | 8 or 9 | dotnet test [<path>] -- <MTP_ARGS> | | MTP | 10+ | dotnet test --project <path> <MTP_ARGS> |
Detection files to always check (in order): global.json -> .csproj -> Directory.Build.props -> Directory.Packages.props
If the prompt names a subset of tests (e.g., "integration tests", "smoke tests", a specific class, a specific TFM), plan to apply the matching filter / --framework in Step 3 — do not run the whole suite.
dotnet --version in the project directory to determine the SDK version. This accounts for global.json SDK pinning.global.json — on .NET SDK 10+, "test": { "runner": "Microsoft.Testing.Platform" } is the authoritative MTP signal. If present, the project uses MTP and SDK 10+ syntax (no -- separator)..csproj, Directory.Build.props, and Directory.Packages.props for framework packages and MTP properties. Always check all three files — MTP properties are frequently set in Directory.Build.props rather than individual .csproj files.platform-detection skill.What to look for in each file:
| File | Look for | Indicates | |------|----------|-----------| | global.json | "test": { "runner": "Microsoft.Testing.Platform" } | MTP on SDK 10+ | | global.json | "sdk": { "version": "..." } | SDK version (determines -- separator behavior) | | .csproj | <TestingPlatformDotnetTestSupport>true | MTP on SDK 8/9 | | .csproj | MSTest, xunit.v3, NUnit, TUnit packages | Framework identity | | .csproj | Microsoft.NET.Test.Sdk + test adapter | VSTest (unless overridden by MTP signals above) | | .csproj | <TargetFrameworks> (plural) | Multi-TFM — may need --framework | | Directory.Build.props | <TestingPlatformDotnetTestSupport>true | MTP on SDK 8/9 (often set here, not in .csproj) | | Directory.Packages.props | Centrally managed test package versions | Framework identity for CPM repos |
Quick detection summary:
| Signal | Means | |--------|-------| | global.json has "test": { "runner": "Microsoft.Testing.Platform" } | MTP on SDK 10+ — pass args directly, no -- | | <TestingPlatformDotnetTestSupport>true in csproj or Directory.Build.props | MTP on SDK 8/9 — pass args after -- | | Neither signal present | VSTest |
bashdotnet test [<PROJECT> | <SOLUTION> | <DIRECTORY> | <DLL> | <EXE>]
Common flags:
| Flag | Description | |------|-------------| | --framework <TFM> | Target a specific framework in multi-TFM projects (e.g., net8.0) | | --no-build | Skip build, use previously built output | | --filter <EXPRESSION> | Run selected tests (see Step 3) | | --logger trx | Generate TRX results file | | --collect "Code Coverage" | Collect code coverage using Microsoft Code Coverage (built-in, always available) | | --blame | Enable blame mode to detect tests that crash the host | | --blame-crash | Collect a crash dump when the test host crashes | | --blame-hang-timeout <duration> | Abort test if it hangs longer than duration (e.g., 5min) | | -v <level> | Verbosity: quiet, minimal, normal, detailed, diagnostic |
With <TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport>, dotnet test bridges to MTP but uses VSTest-style argument parsing. MTP-specific arguments must be passed after --:
bashdotnet test [<PROJECT> | <SOLUTION> | <DIRECTORY> | <DLL> | <EXE>] -- <MTP_ARGUMENTS>
With the global.json runner set to Microsoft.Testing.Platform, dotnet test natively understands MTP arguments without --:
bashdotnet test [--project <PROJECT_OR_DIRECTORY>] [--solution <SOLUTION_OR_DIRECTORY>] [--test-modules <EXPRESSION>] [<MTP_ARGUMENTS>]
Examples:
bash# Run all tests in a project dotnet test --project path/to/MyTests.csproj # Run all tests in a directory containing a project dotnet test --project path/to/ # Run all tests in a solution (sln, slnf, slnx) dotnet test --solution path/to/MySolution.sln dotnet test --solution path/to/MySolution.slnf dotnet test --solution path/to/MySolution.slnx # Run all tests in a directory containing a solution dotnet test --solution path/to/ # Run with MTP flags dotnet test --project path/to/MyTests.csproj --report-trx --blame-hang-timeout 5min
> Note: The .NET 10+ dotnet test syntax does not accept a bare positional argument like the VSTest syntax. Use --project, --solution, or --test-modules to specify the target.
These flags apply to MTP on both SDK versions. On SDK 8/9, pass after --; on SDK 10+, pass directly.
> Important: dotnet test/MSBuild flags such as --framework, --no-build, --configuration, and --verbosity are consumed by dotnet test itself (they drive restore/build/host selection) and always go BEFORE --, regardless of platform or SDK. Only MTP test-platform arguments go after -- on SDK 8/9. For example: dotnet test --framework net9.0 -- --report-trx (built-in flag before --, MTP extension flag after).
Built-in flags (always available):
| Flag | Description | |------|-------------| | --results-directory <DIR> | Directory for test result output | | --diagnostic | Enable diagnostic logging for the test platform | | --diagnostic-output-directory <DIR> | Directory for diagnostic log output |
Extension-dependent flags (require the corresponding extension package to be registered):
| Flag | Requires | Description | |------|----------|-------------| | --filter <EXPRESSION> | Framework-specific (not all frameworks support this) | Run selected tests (see Step 3) | | --report-trx | Microsoft.Testing.Extensions.TrxReport | Generate TRX results file | | --report-trx-filename <FILE> | Microsoft.Testing.Extensions.TrxReport | Set TRX output filename | | --blame-hang-timeout <duration> | Microsoft.Testing.Extensions.HangDump | Abort test if it hangs longer than duration (e.g., 5min) | | --blame-crash | Microsoft.Testing.Extensions.CrashDump | Collect a crash dump when the test host crashes | | --coverage | Microsoft.Testing.Extensions.CodeCoverage | Collect code coverage using Microsoft Code Coverage |
> Some frameworks (e.g., MSTest) bundle common extensions by default. Others may require explicit package references. If a flag is not recognized, check that the corresponding extension package is referenced in the project.
MTP test projects are standalone executables. Beyond dotnet test, they can be run directly:
bash# Build and run dotnet run --project <PROJECT_PATH> # Run a previously built DLL dotnet exec <PATH_TO_DLL> # Run the executable directly (Windows) <PATH_TO_EXE>
These alternative invocations accept MTP command line arguments directly (no -- separator needed).
See the filter-syntax skill for the complete filter syntax for each platform and framework combination. Key points:
dotnet test --filter <EXPRESSION> with =, !=, ~, !~ operators--filter syntax as VSTest; pass after -- on SDK 8/9, directly on SDK 10+--filter-class, --filter-method, --filter-trait (not VSTest expression syntax). For a single combined expression (e.g., a class-name pattern AND a trait), use --filter-query with the xUnit v3 query filter language: path segments /<assembly>/<namespace>/<class>/<method> with * wildcards and a [Trait=Value] qualifier — for example dotnet test -- --filter-query "/*/*/*IntegrationTests*/*[Category=Smoke]". See the filter-syntax skill for the full query language.--treenode-filter with path-based syntaxWhen the prompt names a subset of tests by category (e.g., "integration tests", "unit tests", "smoke tests", "fast tests"), do not run all tests — translate the user's vocabulary into the platform-appropriate filter:
| Framework | Attribute | Filter property | |-----------|-----------|-----------------| | MSTest | [TestCategory("Integration")] | TestCategory | | NUnit | [Category("Integration")] | TestCategory (mapped) | | xUnit v2 | [Trait("Category", "Integration")] | Category | | xUnit v3 | [Trait("Category", "Integration")] | Category (use --filter-trait) | | TUnit | [Category("Integration")] | Category |
| Platform | SDK | Command | |----------|-----|---------| | VSTest (MSTest) | any | dotnet test --filter "TestCategory=Integration" | | MTP (MSTest) | 8 or 9 | dotnet test -- --filter "TestCategory=Integration" | | MTP (MSTest) | 10+ | dotnet test --filter "TestCategory=Integration" | | MTP (xUnit v3) | 8 or 9 | dotnet test -- --filter-trait "Category=Integration" | | MTP (xUnit v3) | 10+ | dotnet test --filter-trait "Category=Integration" | | MTP (TUnit) | 8 or 9 | dotnet test -- --treenode-filter "/*/*/*/*[Category=Integration]" |
--filter "FullyQualifiedName~Integration").dotnet test invocation was used for the detected platform and SDK version| Pitfall | Solution | |---------|----------| | Missing Microsoft.NET.Test.Sdk in a VSTest project | Tests won't be discovered. Add <PackageReference Include="Microsoft.NET.Test.Sdk" /> | | Using VSTest --filter syntax with xUnit v3 on MTP | xUnit v3 on MTP uses --filter-class, --filter-method, etc. -- not the VSTest expression syntax | | Passing MTP args without -- on .NET SDK 8/9 | Before .NET 10, MTP args must go after --: dotnet test -- --report-trx | | Using -- --arg separator on .NET SDK 10+ | SDK 10+ passes MTP args directly — do NOT use -- separator | | Using --logger trx for MTP or --report-trx for VSTest | Each platform has its own TRX flag — check the Critical Rules table | | Only checking .csproj for MTP signals | Always check Directory.Build.props and Directory.Packages.props too — MTP properties are frequently set there | | Using bare positional path argument on SDK 10+ | SDK 10+ requires named flags: --project <path> or --solution <path> |
Common error messages and how to resolve them:
| Error | Cause | Fix | |-------|-------|-----| | No test is available or No test matches the given testcase filter | Wrong filter syntax for the platform/framework, or tests not discovered | Verify filter syntax matches the platform (see filter-syntax skill). For discovery issues, check that the test SDK and adapter packages are installed | | The --report-trx option is unrecognized | MTP extension package not referenced, or using MTP flag on a VSTest project | Add <PackageReference Include="Microsoft.Testing.Extensions.TrxReport" /> for MTP, or use --logger trx for VSTest | | The --blame-hang-timeout option is unrecognized | Missing HangDump extension on MTP | Add <PackageReference Include="Microsoft.Testing.Extensions.HangDump" /> | | error NETSDK1045: The current .NET SDK does not support targeting .NET X.0 | SDK version in global.json doesn't match the project's target framework | Update global.json SDK version or install the required SDK | | The test runner process exited with non-zero exit code | MTP test host crashed or test failure | Run with --blame-crash (MTP) or --blame (VSTest) to collect a crash dump for diagnosis | | No test source files were found / No test project found | dotnet test can't find a test project in the given path | Specify the path explicitly: dotnet test <path/to/project.csproj> (VSTest) or dotnet test --project <path> (SDK 10+) | | Tests discovered but 0 executed | Filter expression matches no tests | Double-check filter property names and values. Common typo: TestCategory (MSTest) vs Category (NUnit) vs trait syntax (xUnit) | | Using -- for MTP args on .NET SDK 10+ | On .NET 10+, MTP args are passed directly: dotnet test --project . --blame-hang-timeout 5min — do NOT use -- --blame-hang-timeout | | Multi-TFM project runs tests for all frameworks | Use --framework <TFM> to target a specific framework | | global.json runner setting ignored | Requires .NET 10+ SDK. On older SDKs, use <TestingPlatformDotnetTestSupport> MSBuild property instead | | TUnit --treenode-filter not recognized | TUnit is MTP-only. On .NET SDK 10+ use dotnet test; on older SDKs use dotnet run since VSTest-mode dotnet test does not support TUnit |
Other measured skills in the registry, with their headline benchmark lift.