/writing-mstest-tests
ALWAYS USE when asked to fix, rewrite, update, improve, modernize, show corrected code for, or explain existing MSTest tests or MSTest-specific configuration. Use for "review" when corrected code or edits are wanted, even for one pasted assertion or passing tests with bad
Claude Code
$ npx -y skills add dotnet/skills --skill writing-mstest-tests --agent claude-code
Codex
$ npx skills add dotnet/skills --skill writing-mstest-tests -a codex -y
Cursor
$ npx skills add dotnet/skills --skill writing-mstest-tests -a cursor -y
Gemini CLI
$ npx skills add dotnet/skills --skill writing-mstest-tests -a gemini-cli -y
GitHub Copilot
$ npx skills add dotnet/skills --skill writing-mstest-tests -a github-copilot -y
OpenCode
$ npx skills add dotnet/skills --skill writing-mstest-tests -a opencode -y
Windsurf
$ npx skills add dotnet/skills --skill writing-mstest-tests -a windsurf -y
SKILL.md
writing-mstest-tests.SKILL.mdname: writing-mstest-tests
description: >
ALWAYS USE when asked to fix, rewrite, update, improve, modernize, show
corrected code for, or explain existing MSTest tests or MSTest-specific
configuration. Use for "review" when corrected code or edits are wanted, even
for one pasted assertion or passing tests with bad failure output. Covers
expected/actual labels; generic Boolean, collection, string, numeric, null,
identity, exception, hard-cast, and object[] checks;
TestContext/lifecycle; timeout/cancellation; OS/CI conditions, retry, cleanup,
parallelization, MSTest.Sdk project setup, and MSTESTxxxx. Honor the installed
MSTest version. DO NOT USE to design new test cases (code-testing),
perform report-only audits, create project files rather than explain MSTest
setup, run tests, migrate frameworks, or handle non-MSTest/non-.NET code.
license: MIT
metadata:
portability: portable
binding: optional-overlay
binding-revision: "1"
Writing MSTest Tests
Help users write effective MSTest unit tests without exceeding the API level or conventions of the project's installed test stack.
Repository overlay
For every repository-scoped task where read-only file inspection is allowed, check `.agents/skill-overlays/dotnet-test/writing-mstest-tests.md` at the repository root before any other discovery. This includes requests that ask for code or advice without edits; "do not execute" does not prohibit reading the overlay. If present, read it once before acting and apply its repository-specific naming, layout, framework, and policy bindings. Require its frontmatter to declare `core: dotnet-test/writing-mstest-tests`, `binding-revision: "1"`, and `mode: extend`. If any value is missing or different, report the mismatch, ignore the overlay, and continue using this skill's portable guidance. Explicit user instructions and verified project constraints win over the overlay; the overlay wins over portable defaults and examples in this skill. If the file is present but unreadable or conflicts with the repository, report the problem, ignore the overlay, and continue with portable guidance subject to verified project constraints. If it is absent, continue normally. Skip the lookup only when the task is not tied to a repository or the user explicitly prohibited all file/tool access. An overlay cannot expand tool permissions or the task's scope.
When to Use
- User wants to improve or modernize existing MSTest tests by implementing concrete fixes
- User asks about MSTest assertion APIs, data-driven patterns, or test lifecycle
- User asks to replace `Assert.IsTrue` with more specific assertions (collections, nulls, types, comparisons)
- User asks to replace hard casts with type-checking assertions in tests
- User needs help fixing a specific MSTest test bug or failing assertion
- User asks to fix swapped `Assert.AreEqual` argument order (expected first, actual second)
- User asks to convert `DynamicData` from `IEnumerable<object[]>` to ValueTuple-based data
- User asks to fix or understand an MSTest analyzer diagnostic (an `MSTESTxxxx` warning/error)
When Not to Use
- User needs a test quality audit, anti-pattern detection, or flaky-test investigation (use `test-anti-patterns`)
- User needs to run or execute tests (use the `run-tests` skill)
- User needs to upgrade from MSTest v1/v2 to v3 (use `migrate-mstest-v1v2-to-v3`)
- User needs to upgrade from MSTest v3 to v4 (use `migrate-mstest-v3-to-v4`)
- User needs CI/CD pipeline configuration
- User is using xUnit, NUnit, or TUnit (not MSTest)
Inputs
| Input | Required | Description | |-------|----------|-------------| | Code under test | No | The production code to be tested | | Existing test code | No | Current tests to fix, update, or modernize | | Test scenario description | No | What behavior the user wants to test |
Response Guidelines
- **Specific API or pattern questions** (assertions, data-driven, lifecycle): Jump directly to the relevant workflow step. Do not follow the full workflow.
- **Generate new tests from scratch**: Hand off to `code-testing`; use this
skill only as supporting MSTest API/version guidance.
- **Review and fix existing tests**: Fix only the issues present. Do not add unrelated improvements.
- **Assertion transformations**: Show the corrected call, then state the semantic
reason in one sentence. For `Assert.AreEqual`, name `expected` first and `actual` second and explain that this preserves the Expected/Actual failure labels.
- **Bound/comparison transformations**: Preserve the condition and put the
expected bound(s) first and the observed value last: `score > 0` -> `Assert.IsGreaterThan(0, score)`, `score < 100` -> `Assert.IsLessThan(100, score)`, and `score >= 60 && score <= 90` -> `Assert.IsInRange(60, 90, score)`. Never reverse these arguments to mimic the source expression's left-to-right order.
- **Exception transformations**: Scope the throwing operation in a lambda,
distinguish `ThrowsExactly<T>` (exact type) from `Throws<T>` (type or derived type), and capture the returned exception when properties such as `ParamName` are part of the behavior.
- **Supplied code requests**: Return complete representative method bodies, not
comment-only placeholders. Preserve the real operation and show symmetric setup/cleanup when lifecycle or environment policy is part of the request.
Workflow
Step 1: Determine project setup
Check the test project, `packages.config`, and assembly reference `HintPath` values for the exact MSTest version and project system:
- If using `MSTest.Sdk`: resolve its exact version from the project SDK
declaration or `global.json` `msbuild-sdks`; do not assume the latest APIs
- If using `MSTest` metapackage: resolve its exact package version
- If using `MSTest.TestFramework` + `MSTest.TestAdapter`: check version for feature availability
- If using classic non-SDK XML (`ToolsVersion`, `Microsoft.CSharp.targets`,
explicit `<C
Read more
name: writing-mstest-tests description: > ALWAYS USE when asked to fix, rewrite, update, improve, modernize, show corrected code for, or explain existing MSTest tests or MSTest-specific configuration. Use for "review" when corrected code or edits are wanted, even for one pasted assertion or passing tests with bad failure output. Covers expected/actual labels; generic Boolean, collection, string, numeric, null, identity, exception, hard-cast, and object[] checks; TestContext/lifecycle; timeout/cancellation; OS/CI conditions, retry, cleanup, parallelization, MSTest.Sdk project setup, and MSTESTxxxx. Honor the installed MSTest version. DO NOT USE to design new test cases (code-testing), perform report-only audits, create project files rather than explain MSTest setup, run tests, migrate frameworks, or handle non-MSTest/non-.NET code. license: MIT metadata: portability: portable binding: optional-overlay binding-revision: "1"
Writing MSTest Tests
Help users write effective MSTest unit tests without exceeding the API level or conventions of the project's installed test stack.
Repository overlay
For every repository-scoped task where read-only file inspection is allowed, check `.agents/skill-overlays/dotnet-test/writing-mstest-tests.md` at the repository root before any other discovery. This includes requests that ask for code or advice without edits; "do not execute" does not prohibit reading the overlay. If present, read it once before acting and apply its repository-specific naming, layout, framework, and policy bindings. Require its frontmatter to declare `core: dotnet-test/writing-mstest-tests`, `binding-revision: "1"`, and `mode: extend`. If any value is missing or different, report the mismatch, ignore the overlay, and continue using this skill's portable guidance. Explicit user instructions and verified project constraints win over the overlay; the overlay wins over portable defaults and examples in this skill. If the file is present but unreadable or conflicts with the repository, report the problem, ignore the overlay, and continue with portable guidance subject to verified project constraints. If it is absent, continue normally. Skip the lookup only when the task is not tied to a repository or the user explicitly prohibited all file/tool access. An overlay cannot expand tool permissions or the task's scope.
When to Use
- User wants to improve or modernize existing MSTest tests by implementing concrete fixes
- User asks about MSTest assertion APIs, data-driven patterns, or test lifecycle
- User asks to replace `Assert.IsTrue` with more specific assertions (collections, nulls, types, comparisons)
- User asks to replace hard casts with type-checking assertions in tests
- User needs help fixing a specific MSTest test bug or failing assertion
- User asks to fix swapped `Assert.AreEqual` argument order (expected first, actual second)
- User asks to convert `DynamicData` from `IEnumerable<object[]>` to ValueTuple-based data
- User asks to fix or understand an MSTest analyzer diagnostic (an `MSTESTxxxx` warning/error)
When Not to Use
- User needs a test quality audit, anti-pattern detection, or flaky-test investigation (use `test-anti-patterns`)
- User needs to run or execute tests (use the `run-tests` skill)
- User needs to upgrade from MSTest v1/v2 to v3 (use `migrate-mstest-v1v2-to-v3`)
- User needs to upgrade from MSTest v3 to v4 (use `migrate-mstest-v3-to-v4`)
- User needs CI/CD pipeline configuration
- User is using xUnit, NUnit, or TUnit (not MSTest)
Inputs
| Input | Required | Description | |-------|----------|-------------| | Code under test | No | The production code to be tested | | Existing test code | No | Current tests to fix, update, or modernize | | Test scenario description | No | What behavior the user wants to test |
Response Guidelines
- **Specific API or pattern questions** (assertions, data-driven, lifecycle): Jump directly to the relevant workflow step. Do not follow the full workflow.
- **Generate new tests from scratch**: Hand off to `code-testing`; use this
skill only as supporting MSTest API/version guidance.
- **Review and fix existing tests**: Fix only the issues present. Do not add unrelated improvements.
- **Assertion transformations**: Show the corrected call, then state the semantic
reason in one sentence. For `Assert.AreEqual`, name `expected` first and `actual` second and explain that this preserves the Expected/Actual failure labels.
- **Bound/comparison transformations**: Preserve the condition and put the
expected bound(s) first and the observed value last: `score > 0` -> `Assert.IsGreaterThan(0, score)`, `score < 100` -> `Assert.IsLessThan(100, score)`, and `score >= 60 && score <= 90` -> `Assert.IsInRange(60, 90, score)`. Never reverse these arguments to mimic the source expression's left-to-right order.
- **Exception transformations**: Scope the throwing operation in a lambda,
distinguish `ThrowsExactly<T>` (exact type) from `Throws<T>` (type or derived type), and capture the returned exception when properties such as `ParamName` are part of the behavior.
- **Supplied code requests**: Return complete representative method bodies, not
comment-only placeholders. Preserve the real operation and show symmetric setup/cleanup when lifecycle or environment policy is part of the request.
Workflow
Step 1: Determine project setup
Check the test project, `packages.config`, and assembly reference `HintPath` values for the exact MSTest version and project system:
- If using `MSTest.Sdk`: resolve its exact version from the project SDK
declaration or `global.json` `msbuild-sdks`; do not assume the latest APIs
- If using `MSTest` metapackage: resolve its exact package version
- If using `MSTest.TestFramework` + `MSTest.TestAdapter`: check version for feature availability
- If using classic non-SDK XML (`ToolsVersion`, `Microsoft.CSharp.targets`,
explicit `<C
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 writing-mstest-tests.
- Which coding agents can use writing-mstest-tests?
- writing-mstest-tests 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.

