/platform-detection
Reference data for detecting the test platform (VSTest vs Microsoft.Testing.Platform) and test framework (MSTest, xUnit, NUnit, TUnit) from project files. DO NOT USE directly — loaded by run-tests, mtp-hot-reload, and migrate-vstest-to-mtp when they need detection logic.
$ npx -y skills add dotnet/skills --skill platform-detection --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/platform-detection
Context preview
The summary Claude sees to decide when to auto-load this skill.
Reference data for detecting the test platform (VSTest vs Microsoft.Testing.Platform) and test framework (MSTest, xUnit, NUnit, TUnit) from project files. DO NOT USE directly — loaded by run-tests, mtp-hot-reload, and migrate-vstest-to-mtp when they need detection logic.
SKILL.md
platform-detection.SKILL.mdname: platform-detection
description: "Reference data for detecting the test platform (VSTest vs Microsoft.Testing.Platform) and test framework (MSTest, xUnit, NUnit, TUnit) from project files. DO NOT USE directly — loaded by run-tests, mtp-hot-reload, and migrate-vstest-to-mtp when they need detection logic."
user-invocable: false
disable-model-invocation: true
license: MIT
Test Platform and Framework Detection
Determine **which test platform** (VSTest or Microsoft.Testing.Platform) and **which test framework** (MSTest, xUnit, NUnit, TUnit) a project uses.
**Detection files to always check** (in order): `global.json` → `.csproj` → `Directory.Build.props` → `Directory.Packages.props`
Detecting the test framework
Read the `.csproj` file **and** `Directory.Build.props` / `Directory.Packages.props` (for centrally managed dependencies) and look for:
| Package or SDK reference | Framework | |--------------------------|-----------| | `MSTest` (metapackage, recommended) or `<Sdk Name="MSTest.Sdk">` | MSTest | | `MSTest.TestFramework` + `MSTest.TestAdapter` | MSTest (also valid for v3/v4) | | `xunit`, `xunit.v3`, `xunit.v3.mtp-v1`, `xunit.v3.mtp-v2`, `xunit.v3.core.mtp-v1`, `xunit.v3.core.mtp-v2` | xUnit | | `NUnit` + `NUnit3TestAdapter` | NUnit | | `TUnit` | TUnit (MTP only) |
Detecting the test platform
The detection logic depends on the .NET SDK version. Run `dotnet --version` to determine it.
.NET SDK 10+
On .NET 10+, the `global.json` `test.runner` setting is the **authoritative source**:
- If `global.json` contains `"test": { "runner": "Microsoft.Testing.Platform" }` → **MTP**
- If `global.json` has `"runner": "VSTest"`, or no `test` section exists → **VSTest**
> **Important**: On .NET 10+, `<TestingPlatformDotnetTestSupport>` alone does **not** switch to MTP. The `global.json` runner setting takes precedence. If the runner is VSTest (or unset), the project uses VSTest regardless of `TestingPlatformDotnetTestSupport`.
.NET SDK 8 or 9
On older SDKs, check these signals in priority order:
**1. Check the `<TestingPlatformDotnetTestSupport>` MSBuild property.** Look in the `.csproj`, `Directory.Build.props`, **and** `Directory.Packages.props`. If set to `true` in **any** of these files, the project uses **MTP**.
> **Critical**: Always read `Directory.Build.props` and `Directory.Packages.props` if they exist. MTP properties are frequently set there instead of in the `.csproj`, so checking only the project file will miss them.
**2. Check project-level signals:**
| Signal | Platform | |--------|----------| | `<Sdk Name="MSTest.Sdk">` as project SDK | **MTP** by default | | `<UseMicrosoftTestingPlatformRunner>true</UseMicrosoftTestingPlatformRunner>` | **MTP** runner (xUnit) | | `<EnableMSTestRunner>true</EnableMSTestRunner>` | **MTP** runner (MSTest) | | `<EnableNUnitRunner>true</EnableNUnitRunner>` | **MTP** runner (NUnit) | | `Microsoft.Testing.Platform` package referenced directly | **MTP** | | `TUnit` package referenced | **MTP** (TUnit is MTP-only) |
> **Note**: The presence of `Microsoft.NET.Test.Sdk` does **not** necessarily mean VSTest. Some frameworks (e.g., MSTest) pull it in transitively for compatibility, even when MTP is enabled. Do not use this package as a signal on its own — always check the MTP signals above first. > **Key distinction**: VSTest is the classic platform that uses `vstest.console` under the hood. Microsoft.Testing.Platform (MTP) is the newer, faster platform. Both can be invoked via `dotnet test`, but their filter syntax and CLI options differ.
Read more
name: platform-detection description: "Reference data for detecting the test platform (VSTest vs Microsoft.Testing.Platform) and test framework (MSTest, xUnit, NUnit, TUnit) from project files. DO NOT USE directly — loaded by run-tests, mtp-hot-reload, and migrate-vstest-to-mtp when they need detection logic." user-invocable: false disable-model-invocation: true license: MIT
Test Platform and Framework Detection
Determine **which test platform** (VSTest or Microsoft.Testing.Platform) and **which test framework** (MSTest, xUnit, NUnit, TUnit) a project uses.
**Detection files to always check** (in order): `global.json` → `.csproj` → `Directory.Build.props` → `Directory.Packages.props`
Detecting the test framework
Read the `.csproj` file **and** `Directory.Build.props` / `Directory.Packages.props` (for centrally managed dependencies) and look for:
| Package or SDK reference | Framework | |--------------------------|-----------| | `MSTest` (metapackage, recommended) or `<Sdk Name="MSTest.Sdk">` | MSTest | | `MSTest.TestFramework` + `MSTest.TestAdapter` | MSTest (also valid for v3/v4) | | `xunit`, `xunit.v3`, `xunit.v3.mtp-v1`, `xunit.v3.mtp-v2`, `xunit.v3.core.mtp-v1`, `xunit.v3.core.mtp-v2` | xUnit | | `NUnit` + `NUnit3TestAdapter` | NUnit | | `TUnit` | TUnit (MTP only) |
Detecting the test platform
The detection logic depends on the .NET SDK version. Run `dotnet --version` to determine it.
.NET SDK 10+
On .NET 10+, the `global.json` `test.runner` setting is the **authoritative source**:
- If `global.json` contains `"test": { "runner": "Microsoft.Testing.Platform" }` → **MTP**
- If `global.json` has `"runner": "VSTest"`, or no `test` section exists → **VSTest**
> **Important**: On .NET 10+, `<TestingPlatformDotnetTestSupport>` alone does **not** switch to MTP. The `global.json` runner setting takes precedence. If the runner is VSTest (or unset), the project uses VSTest regardless of `TestingPlatformDotnetTestSupport`.
.NET SDK 8 or 9
On older SDKs, check these signals in priority order:
**1. Check the `<TestingPlatformDotnetTestSupport>` MSBuild property.** Look in the `.csproj`, `Directory.Build.props`, **and** `Directory.Packages.props`. If set to `true` in **any** of these files, the project uses **MTP**.
> **Critical**: Always read `Directory.Build.props` and `Directory.Packages.props` if they exist. MTP properties are frequently set there instead of in the `.csproj`, so checking only the project file will miss them.
**2. Check project-level signals:**
| Signal | Platform | |--------|----------| | `<Sdk Name="MSTest.Sdk">` as project SDK | **MTP** by default | | `<UseMicrosoftTestingPlatformRunner>true</UseMicrosoftTestingPlatformRunner>` | **MTP** runner (xUnit) | | `<EnableMSTestRunner>true</EnableMSTestRunner>` | **MTP** runner (MSTest) | | `<EnableNUnitRunner>true</EnableNUnitRunner>` | **MTP** runner (NUnit) | | `Microsoft.Testing.Platform` package referenced directly | **MTP** | | `TUnit` package referenced | **MTP** (TUnit is MTP-only) |
> **Note**: The presence of `Microsoft.NET.Test.Sdk` does **not** necessarily mean VSTest. Some frameworks (e.g., MSTest) pull it in transitively for compatibility, even when MTP is enabled. Do not use this package as a signal on its own — always check the MTP signals above first. > **Key distinction**: VSTest is the classic platform that uses `vstest.console` under the hood. Microsoft.Testing.Platform (MTP) is the newer, faster platform. Both can be invoked via `dotnet test`, but their filter syntax and CLI options differ.
This repository contains the .NET team's curated set of core skills and custom agents for coding agents. For information about the Agent Skills standard, see agentskills.io. 📊 Dashboard - Accuracy and efficiency scoring trends for contained plugins (
Repo: dotnet/skills
Other skills on dotnet-skills.
- /csharp-scripts
Run file-based C# apps with the .NET CLI when the user explicitly wants C#/.NET code without creating a project. Use for C# language/API experiments, one-file C# apps, small multi-file C# apps composed with `#:include`/`#:exclude`, or C# file-based apps linked with `#:ref`. Do
Open skill - /dotnet-pinvoke
Correctly call native (C/C++) libraries from .NET using P/Invoke and LibraryImport. Covers function signatures, string marshalling, memory lifetime, SafeHandle, and cross-platform patterns. USE FOR: writing new P/Invoke or LibraryImport declarations, reviewing or debugging
Open skill - /nuget-trusted-publishing
Set up NuGet trusted publishing (OIDC) on a GitHub Actions repo — replaces long-lived API keys with short-lived tokens. USE FOR: trusted publishing, NuGet OIDC, keyless NuGet publish, migrate from NuGet API key, NuGet/login, secure NuGet publishing. DO NOT USE FOR: publishing to
Open skill - /technology-selection
Guides technology selection and implementation of AI and ML features in .NET 8+ applications using ML.NET, Microsoft.Extensions.AI (MEAI), Microsoft Agent Framework (MAF), GitHub Copilot SDK, ONNX Runtime, and OllamaSharp. Covers the full spectrum from classic ML through modern
Open skill - /configuring-opentelemetry-dotnet
Configure OpenTelemetry distributed tracing, metrics, and logging in ASP.NET Core using the .NET OpenTelemetry SDK. Use when adding observability, setting up OTLP exporters, creating custom metrics/spans, or troubleshooting distributed trace correlation.
Open skill - /convert-blazor-server-to-webapp
Guides conversion of a pre-.NET 8 Blazor Server app into a .NET 8+ Blazor Web App. USE FOR: migrating apps that use AddServerSideBlazor and MapBlazorHub to the AddRazorComponents/MapRazorComponents model, converting _Host.cshtml to an App.razor root component, replacing
Open skill

