/migrate-xunit-to-mstest
Convert .NET tests from xUnit.net v2/v3 to MSTest v4 while preserving VSTest or MTP. Use for replacing xunit packages, Fact/Theory/InlineData/MemberData, assertions, IClassFixture/ICollectionFixture, ITestOutputHelper, TestContext cancellation, traits/Owner, skips, timeouts, and
Claude Code
$ npx -y skills add dotnet/skills --skill migrate-xunit-to-mstest --agent claude-code
Codex
$ npx skills add dotnet/skills --skill migrate-xunit-to-mstest -a codex -y
Cursor
$ npx skills add dotnet/skills --skill migrate-xunit-to-mstest -a cursor -y
Gemini CLI
$ npx skills add dotnet/skills --skill migrate-xunit-to-mstest -a gemini-cli -y
GitHub Copilot
$ npx skills add dotnet/skills --skill migrate-xunit-to-mstest -a github-copilot -y
OpenCode
$ npx skills add dotnet/skills --skill migrate-xunit-to-mstest -a opencode -y
Windsurf
$ npx skills add dotnet/skills --skill migrate-xunit-to-mstest -a windsurf -y
SKILL.md
migrate-xunit-to-mstest.SKILL.mdname: migrate-xunit-to-mstest
description: >
Convert .NET tests from xUnit.net v2/v3 to MSTest v4 while preserving VSTest
or MTP. Use for replacing xunit packages, Fact/Theory/InlineData/MemberData,
assertions, IClassFixture/ICollectionFixture, ITestOutputHelper, TestContext
cancellation, traits/Owner, skips, timeouts, and xUnit parallelization. Also
use when a "convert xUnit to MSTest" request may already be migrated: inspect
and report the no-op. Do not use for xUnit v2-to-v3, MSTest upgrades,
NUnit/TUnit conversion, or runner-only VSTest-to-MTP migration.
license: MIT
xUnit -> MSTest Migration
Convert xUnit.net v2 or v3 tests to MSTest v4 without changing the target framework or test platform. A successful migration builds, discovers the same tests, and preserves pass/fail results and execution semantics.
Scope
Use this skill only when the project contains xUnit packages or source and the user wants MSTest. If the project already uses MSTest and contains no xUnit tests, report that no framework migration is needed and make no changes.
Do not combine this framework conversion with a target-framework upgrade or VSTest/MTP migration. Complete and verify one migration before starting another.
Workspace Contract
- Continue after skill activation. Search the current working directory for the
staged project and source; never look for user files under this skill's base directory.
- Open the literal paths returned by glob/search. If one reader or patch tool
rejects a path that was just found, retry with another available tool. Do not ask the user for a path until current-workspace discovery is exhausted.
- Classify by the requested deliverable: "convert this project" means edit,
build, and test; "give me a plan" or "how would I convert it?" means answer. Do not replace execution with "please provide the files" when files are present.
- The final response must state the source xUnit version, preserved runner,
changed files, each high-risk semantic mapping applied, and actual test counts. Assertions about fixture lifetime, Owner mapping, cancellation, or parallelization must be visible in the resulting source, not only prose.
Response Mode
- **Full migration request:** inspect the project, make the edits, build, and run tests. Do not stop after giving a plan.
- **Focused compile error or API question:** inspect the relevant code and apply only that mapping. Do not narrate the entire workflow.
- **Unsupported target framework:** stop before changing packages. MSTest v4 requires .NET 8+ or .NET Framework 4.6.2+ for test applications; offer a separately approved TFM upgrade or MSTest v3 as the intermediate target.
Decisions That Change the Result
Apply these before the mechanical mapping:
| Detected state | Required action | |---|---| | No xUnit package, namespace, attribute, or fixture remains | Stop. Make no file changes, report that migration is unnecessary, and run the existing `dotnet test` command once to prove the already-MSTest project is healthy. | | Source uses VSTest | Keep the existing VSTest property/configuration. Prefer retaining and updating a source project's explicit `Microsoft.NET.Test.Sdk` pin; a repository that intentionally relies on the MSTest metapackage's transitive dependency may keep that convention. Do not introduce MTP properties. | | Source uses MTP | Replace xUnit-specific MTP selection with MSTest MTP configuration. Prefer `MSTest.Sdk`; with the metapackage, set `EnableMSTestRunner=true` and `OutputType=Exe`. Preserve native-versus-bridged command integration, and do not add `<UseVSTest>true</UseVSTest>` or other VSTest-only configuration. | | Source relies on xUnit's default parallelization | Add `[assembly: Parallelize(Workers = 0, Scope = ExecutionScope.ClassLevel)]` to a compiled `.cs` file when the current project has at least two independently runnable test classes. In a one-class project with no explicit parallel setting, omit it because class-level concurrency is not observable. Translate explicit `CollectionBehavior` or `xunit.runner.json` settings regardless of current class count. Before reporting completion, read the changed file back and name it in the result. |
For detailed mappings and examples, search [`references/mapping-cheatsheet.md`](references/mapping-cheatsheet.md) for constructs actually present in the project and read only the matching sections. Do not load or reproduce the whole reference.
Fast Path
For a routine project migration, converge in four phases: one batched discovery read/search, one edit pass, one `dotnet test`, and one concise result. Do not:
- list a directory and then reread the same files through another tool
- copy project files into the loaded skill or its `references/` directory; those files are read-only guidance, not an editing workspace
- try `dotnet test --no-restore` unless restore is already known to be current
- run separate restore, build, and test commands when `dotnet test` is sufficient
- rerun a passing test command or inspect unchanged files for confirmation
Use an existing CI/test result as the parity baseline when available. Run a new pre-edit baseline only when counts are unavailable and the migration contains data-driven tests, fixtures, skips, custom extensions, shared state, or other behavior whose parity cannot be established from source alone.
Workflow
1. Establish the baseline
1. In one discovery pass, batch-read the test projects plus `Directory.Build.props`, `Directory.Packages.props`, `global.json`, and runner configuration, and search the source for the high-risk constructs below. 2. State the detected source version:
- `xunit` 2.x and related packages -> xUnit v2
- `xunit.v3` or `xunit.v3.*` -> xUnit v3
3. Identify VSTest or MTP from the project and repository configuration. Use `platform-detection` only when the platform is ambiguous, and preserve the detected platform. 4. Record the target frameworks and st
Read more
name: migrate-xunit-to-mstest description: > Convert .NET tests from xUnit.net v2/v3 to MSTest v4 while preserving VSTest or MTP. Use for replacing xunit packages, Fact/Theory/InlineData/MemberData, assertions, IClassFixture/ICollectionFixture, ITestOutputHelper, TestContext cancellation, traits/Owner, skips, timeouts, and xUnit parallelization. Also use when a "convert xUnit to MSTest" request may already be migrated: inspect and report the no-op. Do not use for xUnit v2-to-v3, MSTest upgrades, NUnit/TUnit conversion, or runner-only VSTest-to-MTP migration. license: MIT
xUnit -> MSTest Migration
Convert xUnit.net v2 or v3 tests to MSTest v4 without changing the target framework or test platform. A successful migration builds, discovers the same tests, and preserves pass/fail results and execution semantics.
Scope
Use this skill only when the project contains xUnit packages or source and the user wants MSTest. If the project already uses MSTest and contains no xUnit tests, report that no framework migration is needed and make no changes.
Do not combine this framework conversion with a target-framework upgrade or VSTest/MTP migration. Complete and verify one migration before starting another.
Workspace Contract
- Continue after skill activation. Search the current working directory for the
staged project and source; never look for user files under this skill's base directory.
- Open the literal paths returned by glob/search. If one reader or patch tool
rejects a path that was just found, retry with another available tool. Do not ask the user for a path until current-workspace discovery is exhausted.
- Classify by the requested deliverable: "convert this project" means edit,
build, and test; "give me a plan" or "how would I convert it?" means answer. Do not replace execution with "please provide the files" when files are present.
- The final response must state the source xUnit version, preserved runner,
changed files, each high-risk semantic mapping applied, and actual test counts. Assertions about fixture lifetime, Owner mapping, cancellation, or parallelization must be visible in the resulting source, not only prose.
Response Mode
- **Full migration request:** inspect the project, make the edits, build, and run tests. Do not stop after giving a plan.
- **Focused compile error or API question:** inspect the relevant code and apply only that mapping. Do not narrate the entire workflow.
- **Unsupported target framework:** stop before changing packages. MSTest v4 requires .NET 8+ or .NET Framework 4.6.2+ for test applications; offer a separately approved TFM upgrade or MSTest v3 as the intermediate target.
Decisions That Change the Result
Apply these before the mechanical mapping:
| Detected state | Required action | |---|---| | No xUnit package, namespace, attribute, or fixture remains | Stop. Make no file changes, report that migration is unnecessary, and run the existing `dotnet test` command once to prove the already-MSTest project is healthy. | | Source uses VSTest | Keep the existing VSTest property/configuration. Prefer retaining and updating a source project's explicit `Microsoft.NET.Test.Sdk` pin; a repository that intentionally relies on the MSTest metapackage's transitive dependency may keep that convention. Do not introduce MTP properties. | | Source uses MTP | Replace xUnit-specific MTP selection with MSTest MTP configuration. Prefer `MSTest.Sdk`; with the metapackage, set `EnableMSTestRunner=true` and `OutputType=Exe`. Preserve native-versus-bridged command integration, and do not add `<UseVSTest>true</UseVSTest>` or other VSTest-only configuration. | | Source relies on xUnit's default parallelization | Add `[assembly: Parallelize(Workers = 0, Scope = ExecutionScope.ClassLevel)]` to a compiled `.cs` file when the current project has at least two independently runnable test classes. In a one-class project with no explicit parallel setting, omit it because class-level concurrency is not observable. Translate explicit `CollectionBehavior` or `xunit.runner.json` settings regardless of current class count. Before reporting completion, read the changed file back and name it in the result. |
For detailed mappings and examples, search [`references/mapping-cheatsheet.md`](references/mapping-cheatsheet.md) for constructs actually present in the project and read only the matching sections. Do not load or reproduce the whole reference.
Fast Path
For a routine project migration, converge in four phases: one batched discovery read/search, one edit pass, one `dotnet test`, and one concise result. Do not:
- list a directory and then reread the same files through another tool
- copy project files into the loaded skill or its `references/` directory; those files are read-only guidance, not an editing workspace
- try `dotnet test --no-restore` unless restore is already known to be current
- run separate restore, build, and test commands when `dotnet test` is sufficient
- rerun a passing test command or inspect unchanged files for confirmation
Use an existing CI/test result as the parity baseline when available. Run a new pre-edit baseline only when counts are unavailable and the migration contains data-driven tests, fixtures, skips, custom extensions, shared state, or other behavior whose parity cannot be established from source alone.
Workflow
1. Establish the baseline
1. In one discovery pass, batch-read the test projects plus `Directory.Build.props`, `Directory.Packages.props`, `global.json`, and runner configuration, and search the source for the high-risk constructs below. 2. State the detected source version:
- `xunit` 2.x and related packages -> xUnit v2
- `xunit.v3` or `xunit.v3.*` -> xUnit v3
3. Identify VSTest or MTP from the project and repository configuration. Use `platform-detection` only when the platform is ambiguous, and preserve the detected platform. 4. Record the target frameworks and st
This repository contains the .NET team's curated set of portable skills and host-specific custom agents for coding agents. For information about the Agent Skills standard, see agentskills.io.
Other skills on skills.
More skills from other plugins.
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
ask-matt
Ask which skill or flow fits your situation. A router over the skills in this repo.
Questions about migrate-xunit-to-mstest.
- Which coding agents can use migrate-xunit-to-mstest?
- migrate-xunit-to-mstest installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

