.github/skills/run-tests/SKILL.md
Runs .NET tests with dotnet test. Use when user says "run tests", "execute tests", "dotnet test", "test filter", "filter by category", "filter by class", "run only specific tests", "tests not running", "hang timeout", "blame-hang", "blame-crash", "TUnit", "treenode-filter", or needs to detect the test platform (VSTest or Microsoft.Testing.Platform), identify the test framework, apply test filters, or troubleshoot test execution failures. Covers MSTest, xUnit, NUnit, and TUnit across both VSTest and MTP platforms. Also use for --filter-class, --filter-trait, and other framework-specific filter syntax. DO NOT USE FOR: writing or generating test code, CI/CD pipeline configuration, or debugging failing test logic.
npx skillsauth add microsoft/vstest run-testsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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). 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) |
| 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
global.json first — 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.platform-detection skill.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 |
dotnet 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 --:
dotnet 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 --:
dotnet test
[--project <PROJECT_OR_DIRECTORY>]
[--solution <SOLUTION_OR_DIRECTORY>]
[--test-modules <EXPRESSION>]
[<MTP_ARGUMENTS>]
Examples:
# 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
# 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 testsyntax does not accept a bare positional argument like the VSTest syntax. Use--project,--solution, or--test-modulesto specify the target.
These flags apply to MTP on both SDK versions. On SDK 8/9, pass after --; on SDK 10+, pass directly.
Built-in flags (always available):
| Flag | Description |
|------|-------------|
| --no-build | Skip build, use previously built output |
| --framework <TFM> | Target a specific framework in multi-TFM projects |
| --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:
# 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)--treenode-filter with path-based syntaxdotnet 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 -- 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 |
development
Best practices for writing MSTest 3.x/4.x unit tests. Use when the user needs to write, improve, fix, or review MSTest tests, including modern assertions, data-driven tests, test lifecycle, and common anti-patterns. Also use when fixing test issues like swapped Assert.AreEqual arguments, incorrect assertion usage, or modernizing legacy test code. Covers MSTest.Sdk, sealed classes, Assert.Throws, DynamicData with ValueTuples, TestContext, and conditional execution.
development
Build, test, and validate changes in the vstest repository. Use when building vstest projects, running unit tests, smoke tests, or acceptance tests, or when deploying locally built vstest.console for manual testing.
development
Validate that commands documented in skill files actually work. Use when creating, updating, or reviewing skills to ensure all documented commands exit with code 0.
testing
Parse and analyze Visual Studio TRX test result files. Use when asked about slow tests, test durations, test frequency, flaky tests, failure analysis, or test execution patterns from TRX files.