migrate-nunit-to-mstest
Convert .NET tests from NUnit 3/4 to MSTest v4 while preserving VSTest or MTP. Use for replacing NUnit/NUnit3TestAdapter packages, Test/TestCase/ TestCaseSource/Values attributes, constraint assertions, SetUp/TearDown, OneTimeSetUp, SetUpFixture, FixtureLifeCycle, TestContext, categories, retries, t…
Install / Use
npx skills add dotnet/skills --skill migrate-nunit-to-mstestInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
Development & EngineeringSupported Platforms
Tags
Our assessment of migrate-nunit-to-mstest
migrate-nunit-to-mstest scores 87/100 on our quality scale, 880th of 2,398 Development & Engineering skills we index (top 37%).
Its SKILL.md is 15 KB long, well organised into 16 sections with 1 code example: a thorough specification that gives an agent plenty to work with.
With 5,471 GitHub stars, it is one of the more widely adopted skills in the catalogue.
Maintenance, license and trust
- The repository was last updated 2 days ago, so migrate-nunit-to-mstest is actively maintained.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
migrate-nunit-to-mstest compared with similar skills
All 4 of these similar skills score higher than migrate-nunit-to-mstest; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| migrate-nunit-to-mstest (this skill)by dotnet | 87 | 5.5k | 2d ago | SKILL.md |
| ai-job-searchby MadsLorentzen | 100 | 44.0k | 5d ago | CLAUDE.md |
| claude-howtoby luongnv89 | 100 | 41.7k | today | CLAUDE.md |
| algorithmic-artby anthropics | 100 | 177.9k | 4d ago | SKILL.md |
| pptxby anthropics | 100 | 177.9k | 4d ago | SKILL.md |
Frequently asked questions
- How do I install migrate-nunit-to-mstest?
- Run
npx skills add dotnet/skills --skill migrate-nunit-to-mstest. The install tabs above show the steps for each supported agent. - Which AI agents does migrate-nunit-to-mstest work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is migrate-nunit-to-mstest safe to use?
- It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is migrate-nunit-to-mstest still maintained?
- The repository was last updated 2 days ago, so migrate-nunit-to-mstest is actively maintained.
Skill content
View source on GitHubname: migrate-nunit-to-mstest description: > Convert .NET tests from NUnit 3/4 to MSTest v4 while preserving VSTest or MTP. Use for replacing NUnit/NUnit3TestAdapter packages, Test/TestCase/ TestCaseSource/Values attributes, constraint assertions, SetUp/TearDown, OneTimeSetUp, SetUpFixture, FixtureLifeCycle, TestContext, categories, retries, timeouts, and NUnit parallelization. Also use when a "convert NUnit to MSTest" request may already be migrated: inspect and report the no-op. Do not use for NUnit version upgrades, xUnit/TUnit conversion, MSTest upgrades, or runner-only VSTest-to-MTP migration. license: MIT
NUnit -> MSTest Migration
Convert NUnit 3 or 4 tests to MSTest v4 without changing the target framework or test platform. A successful migration builds, discovers the same test cases, and preserves pass/fail, lifecycle, data, filtering, and concurrency semantics.
Scope
Use this skill only when the project contains NUnit packages or source and the user wants MSTest. If the project already uses MSTest and contains no NUnit 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
- Search the current working directory for projects and source; never look for user files under this skill's directory.
- Classify the deliverable: "convert this project" means edit, build, and test; "give me a plan" means answer without editing.
- Preserve the user's requested project scope. Shared props may be changed only when they own NUnit package or runner configuration for that scope.
- The final response must state the source NUnit version, preserved runner, changed files, high-risk semantic mappings, and actual test counts.
Response Mode
- Full migration request: inspect, edit, build, and run tests. Do not stop after a plan.
- Focused compile error or API question: apply only the relevant mapping.
- 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.
Decisions That Change the Result
| Detected state | Required action |
|---|---|
| No NUnit package, namespace, attribute, or constraint remains | Stop, make no changes, and run the existing test command once to prove the already-MSTest project is healthy. |
| Source uses VSTest | Preserve VSTest. Retain and update an explicit Microsoft.NET.Test.Sdk pin when the repository owns one; do not introduce MTP properties. |
| Source uses MTP | Replace NUnit-specific MTP configuration with MSTest MTP configuration. Prefer MSTest.Sdk; with the metapackage set EnableMSTestRunner=true and OutputType=Exe. |
| NUnit uses its default fixture lifecycle | NUnit normally shares one fixture instance across all test cases; MSTest creates a new class instance per test. Move state that must remain class-shared behind static fields initialized by [ClassInitialize], or prove the state is per-test before leaving it as an instance field. |
| NUnit has no Parallelizable configuration | Preserve serial execution. Do not add [assembly: Parallelize]; NUnit and MSTest are both serial by default. |
| NUnit explicitly enables parallel execution | Translate the effective scope and worker count. Never infer method-level parallelism from fixture-level settings. |
For detailed mappings, search references/mapping-cheatsheet.md for constructs present in the project and read only those sections.
Fast Path
For a routine migration, converge in four phases: one batched discovery pass, one edit pass, one dotnet test, and one concise result.
- Use an existing CI/test result as the baseline when available.
- Run a pre-edit baseline when counts are unavailable and the project contains parameterized tests, fixture state, namespace setup, retries, custom attributes, or explicit parallelization.
- Do not run separate restore, build, and test commands when
dotnet testis sufficient. - Do not delete NUnit runner configuration until its behavior has been translated.
Workflow
1. Establish the baseline
- Batch-read test projects, central package files,
global.json,.runsettings,testconfig.json, and NUnit configuration. - Detect NUnit from
NUnit,NUnit3TestAdapter,NUnit.Analyzers,NUnit.Framework,NUnit.Framework.Legacy, andusing NUnit.Framework. - State whether the source is NUnit 3 or 4 from the resolved package version.
- Detect VSTest or MTP and preserve it. Use
platform-detectiononly when ambiguous. - Record target frameworks and stop if MSTest v4 does not support them.
- Inventory high-risk constructs:
[TestFixture(...)],[TestFixtureSource],[FixtureLifeCycle], constructors with parameters[TestCase],[TestCaseSource],TestCaseData,[Values],[Range],[Random],[Sequential],[Pairwise], custom data attributes[Theory],[Datapoint],[DatapointSource], automatic bool/enum datapoints,Assume.That[OneTimeSetUp],[OneTimeTearDown],[SetUpFixture], inheritance-based setupAssert.That,Assert.Multiple,Assert.Throws,Assert.Catch, collection constraints[Parallelizable],[NonParallelizable],[LevelOfParallelism],[Order],[SingleThreaded][Apartment],[RequiresThread],[CancelAfter],[Timeout][Culture],[Platform],[SetCulture],[SetUICulture][Explicit],[Repeat],[Retry],[MaxTime], categories, properties,[TestOf][DefaultFloatingPointTolerance],[NonTestAssembly], and deprecated fixture lifecycle aliases
2. Replace packages without switching runners
Remove NUnit-specific packages being replaced, including NUnit, NUnit3TestAdapter, NUnit.Analyzers, NUnit console runner packages, and NUnit-specific MTP adapters.
Default to the current stable MSTest v4 metapackage resolved from the configured package source:
<PackageReference Include="MSTest" Version="4.4.0" />
The pin is illustrative for the current release; during a real migration resolve and pin the current stable version. Preserve an explicit Microsoft.NET.Test.Sdk dependency for VSTest when the source project owns one. When preserving MTP, prefer MSTest.Sdk; otherwise use EnableMSTestRunner=true and OutputType=Exe.
Do not change TargetFramework. Remove NUnit .runsettings adapter settings only after translating relevant behavior.
3. Perform the mechanical conversion
| NUnit | MSTest |
|---|---|
| [TestFixture] or fixture with tests | [TestClass] |
| [Test] | [TestMethod] |
| [TestCase(...)] | [TestMethod] + [DataRow(...)] |
| [TestCaseSource(nameof(Cases))] | [TestMethod] + [DynamicData(nameof(Cases))] |
| [SetUp] / [TearDown] | [TestInitialize] / [TestCleanup] |
| [OneTimeSetUp] / [OneTimeTearDown] | static [ClassInitialize] / [ClassCleanup] |
| [Category(value)] | [TestCategory(value)] |
| [Property(key, value)] | [TestProperty(key, value)] |
| [Ignore("reason")] | [Ignore("reason")] plus [TestMethod] |
| [Timeout(ms)] | [Timeout(ms)] plus [TestMethod] |
| [Retry(n)] | [Retry(n - 1)] plus [TestMethod] when n > 1; remove it when n = 1 |
Remove using NUnit.Framework; and using NUnit.Framework.Legacy;. Add using Microsoft.VisualStudio.TestTools.UnitTesting; when using the metapackage; MSTest.Sdk supplies an implicit global using.
Do not mechanically seal classes or flatten inherited setup methods.
4. Resolve semantic mappings
Load the mapping cheatsheet for every high-risk construct found in Step 1. These rules are mandatory:
- NUnit's default
LifeCycle.SingleInstancediffers from MSTest's per-test class instances. Preserve class-shared fields explicitly. [OneTimeSetUp]and[OneTimeTearDown]become static MSTest methods. Move any instance state they use to a static holder rather than merely addingstatic.- NUnit
Assert.Throws<T>andThrows.TypeOf<T>require an exact exception type and map toAssert.ThrowsExactly<T>. NUnitAssert.Catch<T>andThrows.InstanceOf<T>permit derived types and map toAssert.Throws<T>. - NUnit
Is.TypeOf<T>maps toAssert.IsExactInstanceOfType<T>;Is.InstanceOf<T>maps toAssert.IsInstanceOfType<T>. - NUnit equality constraints compare sequences element-by-element. Use
Assert.AreSequenceEqualon MSTest 4.3+ orCollectionAssert.AreEqualwith materialized lists; never use reference-basedAssert.AreEqualfor sequences. TestCase(ExpectedResult=...)andTestCaseData.Returns(...)require rewriting the target test to assert the expected result.- Preserve per-row names, categories, and ignores by returning
TestDataRow<T>fromDynamicDatawhen needed. NUnit row properties have no directTestDataRow<T>equivalent and require a custom data source or an explicit metadata decision. - MSTest 4.4 combinatorial attributes can map NUnit
[Combinatorial],[Values],[Range], and[Random]; addusing Microsoft.VisualStudio.TestTools.UnitTesting.Combinatorial;. Constructor semantics differ, so translate NUnit ranges and random bounds explicitly.[Sequential]still requires explicit rows or a custom data source. - NUnit
[Pairwise]has no MSTest built-in. Preserve the exact generated rows inDynamicDataor use a verified pairwiseITestDataSource; full Cartesian combinations change test counts and execution cost. - Convert
[Theory],[Datapoint], and[DatapointSource]into explicitDynamicDataor combinatorial sources. Preserve automatic bool/enum values and the rule that a theory fails when every row violates its assumptions. [Explicit],[Repeat], parameterized fixtures, fixture sources, andAssert.Multiplehave no behavior-identical mechanical mapping. Rewrite deliberately or report manual follow-up; never approximate silently.- NUnit
[Retry(n)]counts the initial attempt, while MSTest[Retry(n)]counts retries after the initial attempt. Subtract one and review NUnitRetryExceptionsfilters separately. [CancelAfter(ms)]maps to[Timeout(ms, CooperativeCancellation = true)]. Under VSTest, remove NUnit's injectedCancellationTokenparameter and use an injected or property-basedTestContext.CancellationToken; VSTest otherwise treats it as missing data. Retain a method token only when the preserved runner is proven to support injection. Expand fixture-level defaults to every affected test and lifecycle method.[Apartment(ApartmentState.STA)]maps to[STATestClass]or[STATestMethod]. SetUseSTASynchronizationContext = truewhen async continuations must remain on the STA thread. MTA is the MSTest default.[RequiresThread]and[SingleThreaded]guarantee thread identity that MSTest attributes do not generally preserve; use a custom executor or report manual follow-up.- Map NUnit platform and culture gates to
OSCondition,ArchitectureCondition, or aMemberConditionhelper. MapSetCultureandSetUICultureto setup/cleanup that saves and restores the original culture. - Expand
[DefaultFloatingPointTolerance]into explicit deltas on every affected assertion. Preserve method-over-fixture-over-assembly precedence.
5. Preserve lifecycle and namespace setup
[SetUp]and[TearDown]remain per-test lifecycle methods.- For NUnit's default single fixture instance, audit every mutable instance field. If tests depend on sharing, use static state created by
[ClassInitialize]and released by[ClassCleanup]. [FixtureLifeCycle(LifeCycle.InstancePerTestCase)]already matches MSTest class instantiation; remove the attribute and keep per-test instance state.[SetUpFixture]is namespace-scoped in NUnit. MSTest assembly initialization is assembly-wide. Use `[AssemblyInitial
Truncated for display — read the full file on GitHub.
Related Skills
ai-job-search
44.0kThe job search that runs on your machine. AI job application framework built on Claude Code: evaluate postings, tailor CVs, write cover letters, prep interviews. Fork it and own it.
claude-howto
41.7kA visual, example-driven guide to Claude Code — from basic concepts to advanced agents, with copy-paste templates that bring immediate value.
algorithmic-art
177.9kCreating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems.
pptx
177.9kUse this skill any time a .pptx or .potx file is involved in any way — as input, output, or both. This includes: creating slide decks, pitch decks, or presentations; reading, parsing, or extracting text from any .pptx or .potx file (even if the extracted content will be used elsewhere, like in an em…
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
