New to Claude Skills? Learn how to install them →

dotnet on GitHub

Run .NET Tests

Free

Efficiently run and filter .NET tests with precise commands.

by dotnet5.1k stars on dotnet/skills
1 views
Updated Aug 10, 2026
Get this skill

Free · Opens the source repo

What Run .NET Tests does

The Run .NET Tests skill is designed to streamline the process of executing tests in .NET projects by automating the generation of the appropriate dotnet test command. This skill is particularly useful for developers who need to run all tests or a specific subset based on various filters, such as class names or traits. It intelligently detects the test platform (VSTest vs Microsoft.Testing.Platform) and the framework in use, ensuring that the correct command syntax is applied based on the SDK version. This capability helps eliminate common mistakes that can arise from manual command entry, especially when working across different test platforms and SDK versions.

With this skill, users can specify the project or solution path, apply filter expressions to run targeted tests, and choose the target framework for their test execution. The skill also provides guidance on the critical rules to avoid cross-platform mistakes, such as using the wrong logger or omitting necessary command flags. This is particularly important as the syntax can vary significantly between VSTest and MTP, and even between different versions of the .NET SDK.

Ideal for .NET developers and testers, this skill enhances productivity by reducing the cognitive load associated with remembering the correct command syntax and flags. Instead of manually constructing commands, users can rely on the skill to generate the accurate command based on their specific project setup. This not only speeds up the testing process but also helps in diagnosing failures by providing the right context for running tests.

Overall, the Run .NET Tests skill is a valuable tool for anyone involved in .NET development and testing, helping to ensure that tests are executed correctly and efficiently, while also providing the necessary support for troubleshooting issues related to test execution.

When to use it

Use this skill when you need to run tests in a .NET project or filter tests based on specific criteria.

When not to use it

This skill is not suitable for writing test code or debugging test logic; use other specialized skills for those tasks.

What you can build with it

Running All Tests

Quickly execute all tests in a .NET project without needing to remember command syntax.

Filtering Specific Tests

Run a subset of tests based on criteria like class names or traits using filter expressions.

Diagnosing Test Failures

Use the skill to generate the correct command for running tests, helping to identify issues with test execution.

How to install Run .NET Tests

View source

1. Install with the skills CLI

npx skills add dotnet/skills/run-tests --agent claude-code

2. Or install it manually

Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.

Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs

Inside SKILL.md

Written by dotnet

Run .NET Tests

Detect the test platform and framework, run tests, and apply filters using dotnet test.

When to Use

  • User wants to run tests in a .NET project
  • User needs to run a subset of tests using filters
  • User needs help detecting which test platform (VSTest vs MTP) or framework is in use
  • User wants to understand the correct filter syntax for their setup

When Not to Use

  • User needs to write or generate test code (use writing-mstest-tests for MSTest, or general coding assistance for other frameworks)
  • User needs to migrate from VSTest to MTP (use migrate-vstest-to-mtp)
  • User wants to iterate on failing tests without rebuilding (use mtp-hot-reload)
  • User needs CI/CD pipeline configuration (use CI-specific skills)
  • User needs to debug a test (use debugging skills)

Inputs

InputRequiredDescription
Project or solution pathNoPath to the test project (.csproj) or solution (.sln, .slnf, .slnx). Defaults to current directory.
Filter expressionNoFilter expression to select specific tests
Target frameworkNoTarget framework moniker to run against (e.g., net8.0)

Critical Rules — Avoid Cross-Platform Mistakes

These are the most common agent mistakes. Internalize before proceeding:

RuleWhy
Do NOT use --logger trx for MTP projectsMTP uses --report-trx (requires the TrxReport extension package)
Do NOT use --report-trx for VSTest projectsVSTest 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 MTPSDK 8/9 requires the separator: dotnet test -- --report-trx
Do NOT use --filter "ClassName=..." with xUnit v3 on MTPxUnit 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 projectsMTP uses --blame-crash and --blame-hang-timeout separately (each requires its extension package)
Do NOT use --collect "Code Coverage" for MTPMTP uses --coverage (requires the CodeCoverage extension package)

Workflow

Quick Reference

PlatformSDKCommand pattern
VSTestAnydotnet test [<path>] [--filter <expr>] [--logger trx]
MTP8 or 9dotnet test [<path>] -- <MTP_ARGS>
MTP10+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.

Step 1: Detect the test platform and framework

  1. Run dotnet --version in the project directory to determine the SDK version. This accounts for global.json SDK pinning.
  2. Read 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).
  3. Read .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.
  4. For full detection logic (SDK 8/9 signals, framework identification), see the platform-detection skill.

What to look for in each file:

FileLook forIndicates
global.json"test": { "runner": "Microsoft.Testing.Platform" }MTP on SDK 10+
global.json"sdk": { "version": "..." }SDK version (determines -- separator behavior)
.csproj<TestingPlatformDotnetTestSupport>trueMTP on SDK 8/9
.csprojMSTest, xunit.v3, NUnit, TUnit packagesFramework identity
.csprojMicrosoft.NET.Test.Sdk + test adapterVSTest (unless overridden by MTP signals above)
.csproj<TargetFrameworks> (plural)Multi-TFM — may need --framework
Directory.Build.props<TestingPlatformDotnetTestSupport>trueMTP on SDK 8/9 (often set here, not in .csproj)
Directory.Packages.propsCentrally managed test package versionsFramework identity for CPM repos

Quick detection summary:

SignalMeans
global.json has "test": { "runner": "Microsoft.Testing.Platform" }MTP on SDK 10+ — pass args directly, no --
<TestingPlatformDotnetTestSupport>true in csproj or Directory.Build.propsMTP on SDK 8/9 — pass args after --
Neither signal presentVSTest

Step 2: Run tests

VSTest (any .NET SDK version)

dotnet test [<PROJECT> | <SOLUTION> | <DIRECTORY> | <DLL> | <EXE>]

Common flags:

FlagDescription
--framework <TFM>Target a specific framework in multi-TFM projects (e.g., net8.0)
--no-buildSkip build, use previously built output
--filter <EXPRESSION>Run selected tests (see Step 3)
--logger trxGenerate TRX results file
--collect "Code Coverage"Collect code coverage using Microsoft Code Coverage (built-in, always available)
--blameEnable blame mode to detect tests that crash the host
--blame-crashCollect 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

MTP with .NET SDK 8 or 9

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>

MTP with .NET SDK 10+

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
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.

Common MTP flags

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):

FlagDescription
--results-directory <DIR>Directory for test result output
--diagnosticEnable 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):

FlagRequiresDescription
--filter <EXPRESSION>Framework-specific (not all frameworks support this)Run selected tests (see Step 3)
--report-trxMicrosoft.Testing.Extensions.TrxReportGenerate TRX results file
--report-trx-filename <FILE>Microsoft.Testing.Extensions.TrxReportSet TRX output filename
--blame-hang-timeout <duration>Microsoft.Testing.Extensions.HangDumpAbort test if it hangs longer than duration (e.g., 5min)
--blame-crashMicrosoft.Testing.Extensions.CrashDumpCollect a crash dump when the test host crashes
--coverageMicrosoft.Testing.Extensions.CodeCoverageCollect 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.

Alternative MTP invocations

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).

Step 3: Run filtered tests

See the filter-syntax skill for the complete filter syntax for each platform and framework combination. Key points:

  • VSTest (MSTest, xUnit v2, NUnit): dotnet test --filter <EXPRESSION> with =, !=, ~, !~ operators
  • MTP -- MSTest and NUnit: Same --filter syntax as VSTest; pass after -- on SDK 8/9, directly on SDK 10+
  • MTP -- xUnit v3: Uses --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.
  • MTP -- TUnit: Uses --treenode-filter with path-based syntax

When the user names a test category, trait, or group

When 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:

  1. Inspect the test source files for filter-attribute annotations that match the named group:

    FrameworkAttributeFilter 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
  2. Build the filter expression and combine it with the platform-correct invocation. For "run the integration tests" against an MSTest project:

    PlatformSDKCommand
    VSTest (MSTest)anydotnet test --filter "TestCategory=Integration"
    MTP (MSTest)8 or 9dotnet test -- --filter "TestCategory=Integration"
    MTP (MSTest)10+dotnet test --filter "TestCategory=Integration"
    MTP (xUnit v3)8 or 9dotnet test -- --filter-trait "Category=Integration"
    MTP (xUnit v3)10+dotnet test --filter-trait "Category=Integration"
    MTP (TUnit)8 or 9dotnet test -- --treenode-filter "/*/*/*/*[Category=Integration]"
  3. If you cannot find a matching attribute, ask the user to confirm the category name or fall back to a name-pattern filter (e.g., --filter "FullyQualifiedName~Integration").

Validation

  • Test platform (VSTest or MTP) was correctly identified
  • Test framework (MSTest, xUnit, NUnit, TUnit) was correctly identified
  • Correct dotnet test invocation was used for the detected platform and SDK version
  • When the user named a test category/trait/group, the appropriate filter was applied (not "run all tests")
  • Filter expressions used the syntax appropriate for the platform and framework
  • Test results were clearly reported to the user

Common Pitfalls

PitfallSolution
Missing Microsoft.NET.Test.Sdk in a VSTest projectTests won't be discovered. Add <PackageReference Include="Microsoft.NET.Test.Sdk" />
Using VSTest --filter syntax with xUnit v3 on MTPxUnit v3 on MTP uses --filter-class, --filter-method, etc. -- not the VSTest expression syntax
Passing MTP args without -- on .NET SDK 8/9Before .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 VSTestEach platform has its own TRX flag — check the Critical Rules table
Only checking .csproj for MTP signalsAlways 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>

Troubleshooting

Common error messages and how to resolve them:

ErrorCauseFix
No test is available or No test matches the given testcase filterWrong filter syntax for the platform/framework, or tests not discoveredVerify 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 unrecognizedMTP extension package not referenced, or using MTP flag on a VSTest projectAdd <PackageReference Include="Microsoft.Testing.Extensions.TrxReport" /> for MTP, or use --logger trx for VSTest
The --blame-hang-timeout option is unrecognizedMissing HangDump extension on MTPAdd <PackageReference Include="Microsoft.Testing.Extensions.HangDump" />
error NETSDK1045: The current .NET SDK does not support targeting .NET X.0SDK version in global.json doesn't match the project's target frameworkUpdate global.json SDK version or install the required SDK
The test runner process exited with non-zero exit codeMTP test host crashed or test failureRun with --blame-crash (MTP) or --blame (VSTest) to collect a crash dump for diagnosis
No test source files were found / No test project founddotnet test can't find a test project in the given pathSpecify the path explicitly: dotnet test <path/to/project.csproj> (VSTest) or dotnet test --project <path> (SDK 10+)
Tests discovered but 0 executedFilter expression matches no testsDouble-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 frameworksUse --framework <TFM> to target a specific framework
global.json runner setting ignoredRequires .NET 10+ SDK. On older SDKs, use <TestingPlatformDotnetTestSupport> MSBuild property instead
TUnit --treenode-filter not recognizedTUnit 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

Frequently asked questions about Run .NET Tests

Similar skills