Testing Testing v0.2.0

Run .NET Tests

Run, filter, or troubleshoot .NET tests with `dotnet test`. USE FOR: running all tests in a project or solution; running only a subset (a specific test class, category, or trait) via filters; running a single target framework in a multi-TFM project (`--framework`); producing TRX reports; collecting crash or hang dumps; diagnosing why `dotnet test` fails or uses the wrong argument syntax. Detects the test platform (VSTest vs Microsoft.Testing.Platform) and framework (MSTest/xUnit/NUnit/TUnit), then picks the matching command: the `--` separator on .NET SDK 8/9 vs 10+, the right filter flag (--filter, --filter-class, --filter-trait, --filter-query, --treenode-filter), and TRX/blame flags. DO NOT USE FOR: writing test code (use code-testing-agent), iterating on failing tests without rebuilding (use mtp-hot-reload), CI/CD config, or debugging test logic.

Workflow

Quick Reference

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

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:

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

Step 2: Run tests

#### VSTest (any .NET SDK version)

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 |

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

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

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

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

  1. Build the filter expression and combine it with the platform-correct invocation. For "run the integration tests" against an MSTest project:

| 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]" |

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

Related skills

Testing Testing 1,167 tokens

Use the open-source free `coverlet` toolchain for .NET code coverage.

coverlet.collectorcoverlet.msbuild
Testing Testing 1,227 tokens

Write, run, or repair .NET tests that use MSTest.

MSTestMSTest.TestFrameworkMSTest.TestAdapter
Testing Testing 2,543 tokens

Write, run, or repair .NET tests that use NUnit.

NUnitNUnit3TestAdapter