Skip to content
Development
Skill

/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

From plugin
dotnet-skills
5.1k96 skills16 agents
Install
$ npx -y skills add dotnet/skills --skill migrate-vstest-to-mtp --agent claude-code

How 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.md
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
Read more
Ships withdotnet-skills

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 (

Get the whole plugin

Other skills on dotnet-skills.