/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 managedcode/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
Stop explaining .NET to your AI. Start building. We've all been there: asking Claude to use Entity Framework, only to get EF6 patterns in a .NET 8 project. Explaining to Copilot that Blazor Server and Blazor WebAssembly aren't the same thing.
Repo: managedcode/dotnet-skills
Other skills on dotnet-skills.
- /aspnet-core
Build, debug, modernize, or review ASP.NET Core applications with correct hosting, middleware, security, configuration, logging, and deployment patterns on current .NET. USE FOR: working on ASP.NET Core apps, services, or middleware; changing auth, routing, configuration,
Open skill - /aspire
Build, upgrade, and operate Aspire 13.4.x C# or TypeScript application hosts with the current CLI, AppHost, ServiceDefaults, integrations, dashboard, testing, MCP, and deployment patterns for distributed apps. USE FOR: Aspire.AppHost.Sdk, Aspire.Hosting.*,
Open skill - /azure-functions
Build, review, or migrate Azure Functions in .NET with correct execution model, isolated worker setup, bindings, DI, and Durable Functions patterns. USE FOR: working on Azure Functions in .NET; migrating from the in-process model to the isolated worker model; adding Durable
Open skill - /blazor
Build and review Blazor applications across server, WebAssembly, web app, and hybrid scenarios with correct component design, state flow, rendering, and hosting choices. USE FOR: building interactive web UIs with C# instead of JavaScript; choosing between Server, WebAssembly, or
Open skill - /entity-framework6
Maintain or migrate EF6-based applications with realistic guidance on what to keep, what to modernize, and when EF Core is or is not the right next step. USE FOR: EF6 codebases; runtime versus ORM migration decisions; EDMX, code-first, ObjectContext, and legacy data-access
Open skill - /entity-framework-core
Design, tune, or review EF Core data access with proper modeling, migrations, query translation, performance, and lifetime management for modern .NET applications. USE FOR: DbContext, migrations, model configuration, EF queries, tracking, loading, performance, transactions, and
Open skill

