/migrate-vstest-to-mtp
Migrates .NET test projects from VSTest to Microsoft.Testing.Platform (MTP). Use when user asks to "migrate to MTP", "switch from VSTest", "enable Microsoft.Testing.Platform", "use MTP runner", set OutputType=Exe only for test projects in Directory.Build.props, or mentions
$ npx -y skills add dotnet/skills --skill migrate-vstest-to-mtp --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
/migrate-vstest-to-mtp
Context preview
The summary Claude sees to decide when to auto-load this skill.
Migrates .NET test projects from VSTest to Microsoft.Testing.Platform (MTP). Use when user asks to "migrate to MTP", "switch from VSTest", "enable Microsoft.Testing.Platform", "use MTP runner", set OutputType=Exe only for test projects in Directory.Build.props, or mentions
SKILL.md
migrate-vstest-to-mtp.SKILL.mdname: migrate-vstest-to-mtp
description: >
Migrates .NET test projects from VSTest to Microsoft.Testing.Platform (MTP).
Use when user asks to "migrate to MTP", "switch from VSTest", "enable
Microsoft.Testing.Platform", "use MTP runner", set OutputType=Exe only for
test projects in Directory.Build.props, or mentions EnableMSTestRunner,
EnableNUnitRunner, or UseMicrosoftTestingPlatformRunner.
USE FOR: MTP behavioral differences vs VSTest (exit code 8, zero tests
discovered, --ignore-exit-code, TESTINGPLATFORM_EXITCODE_IGNORE);
centralizing MTP properties and OutputType=Exe on test projects via
MSBuildProjectName, not IsTestProject.
Supports MSTest, NUnit, xUnit.net v2 (via YTest.MTP.XUnit2), and
xUnit.net v3. Covers runner enablement, CLI argument and filter
translation (--filter-class/--filter-trait/--filter-query),
global.json config, CI/CD updates, and extension packages.
DO NOT USE FOR: migrating between test frameworks (MSTest/xUnit/NUnit),
xUnit.net v2 to v3 API migration, MSTest version upgrades, TFM upgrades,
or UWP/WinUI test projects.
license: MIT
VSTest -> Microsoft.Testing.Platform Migration
Migrate a .NET test solution from VSTest to Microsoft.Testing.Platform (MTP). The outcome is a solution where all test projects run on MTP, `dotnet test` works correctly, and CI/CD pipelines are updated.
> **Important**: Do not mix VSTest-based and MTP-based .NET test projects in the same solution or run configuration -- this is an unsupported scenario.
When to Use
- Switching from VSTest to Microsoft.Testing.Platform for any supported test framework
- Enabling `dotnet run` / `dotnet watch` / direct executable execution for test projects
- Enabling Native AOT or trimmed test execution
- Replacing `vstest.console.exe` with `dotnet test` on MTP
- Updating CI/CD pipelines from the VSTest task to the .NET Core CLI task
- Updating `dotnet test` arguments from VSTest syntax to MTP syntax
When Not to Use
- The project already runs on Microsoft.Testing.Platform and there is no remaining MTP behavioral difference to resolve (e.g., exit code 8 for zero tests discovered)
- Migrating between test frameworks (e.g., MSTest to xUnit.net) -- different effort entirely
- The project builds UWP or packaged WinUI test projects -- MTP does not support these yet
- The solution mixes .NET and non-.NET test adapters (e.g., JavaScript or C++ adapters) -- VSTest is required
- Upgrading MSTest versions -- use `migrate-mstest-v1v2-to-v3` or `migrate-mstest-v3-to-v4`
Inputs
| Input | Required | Description | |-------|----------|-------------| | Project or solution path | No | The `.csproj`, `.sln`, or `.slnx` entry point containing test projects. **Discover it yourself** by globbing the working directory; ask only when nothing is found or the choice is genuinely ambiguous | | Test framework | No | MSTest, NUnit, xUnit.net v2, or xUnit.net v3. Auto-detected from package references | | .NET SDK version | No | Determines `dotnet test` integration mode. Auto-detected via `dotnet --version` | | CI/CD pipeline files | No | Paths to pipeline definitions that invoke `vstest.console` or `dotnet test` |
Workflow
Step 1: Assess the solution
1. Identify the test framework for each test project -- see the `platform-detection` skill for the package-to-framework mapping. Key indicators:
- **MSTest**: References `MSTest` or `MSTest.TestAdapter`, or uses `MSTest.Sdk` (with `<IsTestApplication>` not set to `false`). Note: `MSTest.TestFramework` alone is a library dependency, not a test project.
- **NUnit**: References `NUnit3TestAdapter`
- **xUnit.net**: References `xunit` and `xunit.runner.visualstudio`
2. Check the .NET SDK version (`dotnet --version`) -- this determines how `dotnet test` integrates with MTP 3. Check whether a `Directory.Build.props` file exists at the solution or repo root -- all MTP properties should go there for consistency 4. Check for `vstest.console.exe` usage in CI scripts or pipeline definitions 5. Check for VSTest-specific `dotnet test` arguments in CI scripts: `--filter`, `--logger`, `--collect`, `--settings`, `--blame*` 6. Run `dotnet test` to establish a baseline of test pass/fail counts
Step 2: Set up Directory.Build.props
> **Critical**: Set MTP runner properties in `Directory.Build.props` at the solution or repo root whenever possible, rather than per-project. This prevents inconsistent configuration where some projects use VSTest and others use MTP (an unsupported scenario). > **Note**: MTP also requires test projects to have `<OutputType>Exe</OutputType>`. Only `MSTest.Sdk` sets this automatically. For all other setups (MSTest NuGet packages with `EnableMSTestRunner`, NUnit with `EnableNUnitRunner`, xUnit.net with `YTest.MTP.XUnit2`), prefer setting `<OutputType>Exe</OutputType>` centrally in `Directory.Build.props` with a condition that targets only test projects. If you cannot reliably target only test projects from `Directory.Build.props`, setting `<OutputType>Exe</OutputType>` per-project is an acceptable exception. > > **Conditioning in `Directory.Build.props`**: Do NOT use `Condition="'$(IsTestProject)' == 'true'"` -- `IsTestProject` is set by the test SDK targets later in evaluation and is not available when `Directory.Build.props` is imported. Use a property that is available early, such as `MSBuildProjectName`, to target test projects by naming convention. For example, if all test projects end in `.Tests`: > > ```xml > <PropertyGroup Condition="$(MSBuildProjectName.EndsWith('.Tests'))"> > <OutputType>Exe</OutputType> > </PropertyGroup> > ``` > > Adjust the condition (e.g., `.EndsWith('Tests')`, `.Contains('.Test')`) to match the test project naming convention used in the repository.
Step 3: Enable the framework-specific MTP runner
Each framework has its own opt-in property. Add these in `Directory.Build.props` for consistency.
MSTest
**Option A -- MSTest NuGet packages (3.2.0+):**
<Prop
Read more
name: migrate-vstest-to-mtp description: > Migrates .NET test projects from VSTest to Microsoft.Testing.Platform (MTP). Use when user asks to "migrate to MTP", "switch from VSTest", "enable Microsoft.Testing.Platform", "use MTP runner", set OutputType=Exe only for test projects in Directory.Build.props, or mentions EnableMSTestRunner, EnableNUnitRunner, or UseMicrosoftTestingPlatformRunner. USE FOR: MTP behavioral differences vs VSTest (exit code 8, zero tests discovered, --ignore-exit-code, TESTINGPLATFORM_EXITCODE_IGNORE); centralizing MTP properties and OutputType=Exe on test projects via MSBuildProjectName, not IsTestProject. Supports MSTest, NUnit, xUnit.net v2 (via YTest.MTP.XUnit2), and xUnit.net v3. Covers runner enablement, CLI argument and filter translation (--filter-class/--filter-trait/--filter-query), global.json config, CI/CD updates, and extension packages. DO NOT USE FOR: migrating between test frameworks (MSTest/xUnit/NUnit), xUnit.net v2 to v3 API migration, MSTest version upgrades, TFM upgrades, or UWP/WinUI test projects. license: MIT
VSTest -> Microsoft.Testing.Platform Migration
Migrate a .NET test solution from VSTest to Microsoft.Testing.Platform (MTP). The outcome is a solution where all test projects run on MTP, `dotnet test` works correctly, and CI/CD pipelines are updated.
> **Important**: Do not mix VSTest-based and MTP-based .NET test projects in the same solution or run configuration -- this is an unsupported scenario.
When to Use
- Switching from VSTest to Microsoft.Testing.Platform for any supported test framework
- Enabling `dotnet run` / `dotnet watch` / direct executable execution for test projects
- Enabling Native AOT or trimmed test execution
- Replacing `vstest.console.exe` with `dotnet test` on MTP
- Updating CI/CD pipelines from the VSTest task to the .NET Core CLI task
- Updating `dotnet test` arguments from VSTest syntax to MTP syntax
When Not to Use
- The project already runs on Microsoft.Testing.Platform and there is no remaining MTP behavioral difference to resolve (e.g., exit code 8 for zero tests discovered)
- Migrating between test frameworks (e.g., MSTest to xUnit.net) -- different effort entirely
- The project builds UWP or packaged WinUI test projects -- MTP does not support these yet
- The solution mixes .NET and non-.NET test adapters (e.g., JavaScript or C++ adapters) -- VSTest is required
- Upgrading MSTest versions -- use `migrate-mstest-v1v2-to-v3` or `migrate-mstest-v3-to-v4`
Inputs
| Input | Required | Description | |-------|----------|-------------| | Project or solution path | No | The `.csproj`, `.sln`, or `.slnx` entry point containing test projects. **Discover it yourself** by globbing the working directory; ask only when nothing is found or the choice is genuinely ambiguous | | Test framework | No | MSTest, NUnit, xUnit.net v2, or xUnit.net v3. Auto-detected from package references | | .NET SDK version | No | Determines `dotnet test` integration mode. Auto-detected via `dotnet --version` | | CI/CD pipeline files | No | Paths to pipeline definitions that invoke `vstest.console` or `dotnet test` |
Workflow
Step 1: Assess the solution
1. Identify the test framework for each test project -- see the `platform-detection` skill for the package-to-framework mapping. Key indicators:
- **MSTest**: References `MSTest` or `MSTest.TestAdapter`, or uses `MSTest.Sdk` (with `<IsTestApplication>` not set to `false`). Note: `MSTest.TestFramework` alone is a library dependency, not a test project.
- **NUnit**: References `NUnit3TestAdapter`
- **xUnit.net**: References `xunit` and `xunit.runner.visualstudio`
2. Check the .NET SDK version (`dotnet --version`) -- this determines how `dotnet test` integrates with MTP 3. Check whether a `Directory.Build.props` file exists at the solution or repo root -- all MTP properties should go there for consistency 4. Check for `vstest.console.exe` usage in CI scripts or pipeline definitions 5. Check for VSTest-specific `dotnet test` arguments in CI scripts: `--filter`, `--logger`, `--collect`, `--settings`, `--blame*` 6. Run `dotnet test` to establish a baseline of test pass/fail counts
Step 2: Set up Directory.Build.props
> **Critical**: Set MTP runner properties in `Directory.Build.props` at the solution or repo root whenever possible, rather than per-project. This prevents inconsistent configuration where some projects use VSTest and others use MTP (an unsupported scenario). > **Note**: MTP also requires test projects to have `<OutputType>Exe</OutputType>`. Only `MSTest.Sdk` sets this automatically. For all other setups (MSTest NuGet packages with `EnableMSTestRunner`, NUnit with `EnableNUnitRunner`, xUnit.net with `YTest.MTP.XUnit2`), prefer setting `<OutputType>Exe</OutputType>` centrally in `Directory.Build.props` with a condition that targets only test projects. If you cannot reliably target only test projects from `Directory.Build.props`, setting `<OutputType>Exe</OutputType>` per-project is an acceptable exception. > > **Conditioning in `Directory.Build.props`**: Do NOT use `Condition="'$(IsTestProject)' == 'true'"` -- `IsTestProject` is set by the test SDK targets later in evaluation and is not available when `Directory.Build.props` is imported. Use a property that is available early, such as `MSBuildProjectName`, to target test projects by naming convention. For example, if all test projects end in `.Tests`: > > ```xml > <PropertyGroup Condition="$(MSBuildProjectName.EndsWith('.Tests'))"> > <OutputType>Exe</OutputType> > </PropertyGroup> > ``` > > Adjust the condition (e.g., `.EndsWith('Tests')`, `.Contains('.Test')`) to match the test project naming convention used in the repository.
Step 3: Enable the framework-specific MTP runner
Each framework has its own opt-in property. Add these in `Directory.Build.props` for consistency.
MSTest
**Option A -- MSTest NuGet packages (3.2.0+):**
<Prop
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

