How the dotnet-test-migration Plugin Handles Test Migration in .NET Projects

The dotnet-test-migration plugin orchestrates test migration through a three-phase workflow involving detection of current frameworks, routing to specialized migration skills, and step-by-step execution with safety guardrails that ensure the repository remains buildable and test-passing after each commit.

The dotnet-test-migration plugin, part of the dotnet/skills repository, automates the complex process of upgrading .NET test frameworks and switching test runner platforms. It supports migrations between MSTest, xUnit, NUnit, and TUnit, as well as transitions from VSTest to the Microsoft.Testing.Platform. The implementation relies on a deterministic agent-based architecture defined in plugins/dotnet-test-migration/agents/test-migration.agent.md and specialized skill definitions for each migration path.

Detection Phase: Identifying Test Frameworks and Platforms

The migration process begins with an automated detection workflow that scans repository files to determine the current test configuration. The agent examines *.csproj, Directory.Build.props, Directory.Packages.props, and global.json files to extract three critical data points:

  • Test Framework Identity: Identifies whether the project uses MSTest, xUnit, NUnit, or TUnit.
  • Framework Version: Distinguishes between major versions, such as MSTest v2 versus v3, or xUnit v2 versus v3.
  • Test Runner Platform: Determines if tests run on VSTest or the newer Microsoft.Testing.Platform.

This detection logic serves as the foundation for all subsequent routing decisions, ensuring the plugin applies the correct migration strategy based on the actual state of the codebase rather than user assumptions.

Routing Logic: Selecting the Appropriate Migration Skill

Once detection completes, the agent consults a routing table (defined in test-migration.agent.md lines 46-53) to select the appropriate migration skill. Each skill represents a complete, atomic migration path between specific framework or platform versions:

  • migrate-mstest-v1v2-to-v3 – Upgrades legacy MSTest installations to version 3.
  • migrate-mstest-v3-to-v4 – Advances MSTest from version 3 to version 4.
  • migrate-xunit-to-xunit-v3 – Updates xUnit from version 2 to version 3.
  • migrate-xunit-to-mstest – Converts xUnit test suites to MSTest version 4.
  • migrate-vstest-to-mtp – Migrates the test execution platform from VSTest to Microsoft.Testing.Platform.

Each skill is documented in its own SKILL.md file within the plugins/dotnet-test-migration/skills/ directory, containing framework-specific transformation rules and validation steps.

Execution and Safety Rules

Every migration skill follows a standardized, multi-step execution pattern designed to maintain repository integrity throughout the transformation process.

Multi-Step Migration Workflow

The detailed workflow defined in each skill's SKILL.md file typically spans thirteen distinct steps:

  1. Project Assessment – Verifies the target Target Framework Moniker (TFM) compatibility and inventories high-risk patterns such as parallelization, shared fixtures, and test state dependencies.
  2. Package Reference Replacement – Removes legacy NuGet packages (e.g., xUnit assemblies) and introduces modern equivalents (e.g., MSTest metapackage or MSTest.Sdk).
  3. Configuration Conversion – Updates project files and SDK references to support the new framework capabilities.
  4. Code Transformation – Converts test classes, methods, data-driven tests, assertions, fixtures, output helpers, and assembly-level attributes to match the target framework's API surface.
  5. Verification – Executes the build, runs the full test suite, and compares pass/fail counts against the baseline metrics recorded before migration began.

Safety Guardrails

The agent enforces strict safety rules to prevent destructive changes:

  • Atomic Commits: Only one migration skill executes per commit, ensuring the project remains buildable and tests remain passing at every step.
  • Parallelization Verification: Explicitly validates changes to parallel execution behavior, noting that xUnit runs classes in parallel by default while MSTest defaults to serial execution.
  • Scope Communication: Clearly documents any scope-widening changes, such as converting ICollectionFixture to assembly-wide fixtures.
  • Platform Preservation: Maintains the original test platform unless the user explicitly requests a platform switch, preventing accidental runner changes during framework upgrades.

Practical Migration Examples

The plugin accepts structured JSON requests to initiate specific migration workflows.

Example 1: General Test Migration Request

When the user provides an open-ended request, the plugin runs detection to determine the optimal migration path:

{
  "plugin": "dotnet-test-migration",
  "request": "migrate my tests",
  "options": {
    "projectPath": "src/MyApp.Tests.csproj"
  }
}

The orchestrator detects xUnit v2 on VSTest and automatically selects the migrate-xunit-to-mstest skill. It executes the thirteen-step workflow, creating commits after steps 2, 6, and 8, then reports the final migration summary.

Example 2: Direct MSTest Version Upgrade

Explicit version upgrade requests bypass detection and route directly to the appropriate skill chain:

{
  "plugin": "dotnet-test-migration",
  "request": "upgrade MSTest to v4",
  "projectPath": "tests/UnitTests.csproj"
}

If the current version is v2, the agent queues migrate-mstest-v1v2-to-v3 followed by migrate-mstest-v3-to-v4. Each skill manages its own commit points to ensure a clean, incremental transition.

Example 3: Platform Migration to Microsoft.Testing.Platform

To switch test runners while preserving the test framework:

{
  "plugin": "dotnet-test-migration",
  "request": "migrate to MTP",
  "projectPath": "tests/IntegrationTests.csproj"
}

The agent detects the VSTest runner and routes to migrate-vstest-to-mtp. This skill updates the SDK reference, adds <UseMicrosoftTestingPlatformRunner>true</UseMicrosoftTestingPlatformRunner> to the project file, and validates the build before committing changes.

Key Source Files and Architecture

The dotnet-test-migration plugin architecture consists of declarative configuration files and procedural skill definitions:

Summary

  • The dotnet-test-migration plugin implements a deterministic three-phase workflow: detection, routing, and execution with strict safety guardrails.
  • It supports migrations between MSTest (v1/v2/v3/v4), xUnit (v2/v3), NUnit, and TUnit, plus platform switches between VSTest and Microsoft.Testing.Platform.
  • Each migration skill follows a standardized thirteen-step process defined in individual SKILL.md files, ensuring consistency across different framework transformations.
  • Safety rules enforce atomic commits, baseline test comparison, and explicit handling of behavioral differences like parallelization settings.
  • The routing table in test-migration.agent.md (lines 46-53) automatically selects appropriate skills based on detected project state or explicit user intent.

Frequently Asked Questions

What test frameworks does the dotnet-test-migration plugin support?

The plugin supports MSTest (versions 1, 2, 3, and 4), xUnit (versions 2 and 3), NUnit, and TUnit. It can migrate between any of these frameworks in either direction, though the most common paths involve upgrading to newer MSTest versions or converting from xUnit to MSTest v4.

How does the plugin ensure tests still pass after migration?

Each migration skill includes a verification step that builds the project and executes the full test suite, comparing pass/fail counts against baseline metrics captured before the migration began. Additionally, the agent enforces single-migration-per-commit rules, ensuring the repository remains in a healthy, buildable state throughout the transformation process.

Can I migrate from xUnit to MSTest using this plugin?

Yes, the migrate-xunit-to-mstest skill provides a comprehensive thirteen-step workflow for converting xUnit v2 test suites to MSTest v4. This includes replacing package references with MSTest.Sdk or the MSTest metapackage, converting [Fact] and [Theory] attributes to [TestMethod] and [DataRow], transforming assertions, and handling fixture lifecycle differences using the mapping cheatsheet in references/mapping-cheatsheet.md.

What is the difference between VSTest and Microsoft.Testing.Platform migration?

VSTest (Visual Studio Test Platform) is the legacy test runner integrated with Visual Studio and dotnet test. Microsoft.Testing.Platform (MTP) is a newer, lighter-weight test execution framework. The migrate-vstest-to-mtp skill handles this transition by updating SDK references, adding the <UseMicrosoftTestingPlatformRunner>true</UseMicrosoftTestingPlatformRunner> property, and ensuring compatibility with the existing test framework while improving execution performance and reducing overhead.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →