scaffold-dotnet-test-project
Skill1.1k starsChanged 23 days agoMITView on GitHub
MUST USE when an existing .NET test project was excluded from a .slnf/CI solution filter, disappeared from .sln/.slnx discovery, or lost its production ProjectReference; also for requests to set up, create, reuse, add, register, include, or repair a test project. Handles "tests pass directly but CI discovers zero", exact solution wiring, xUnit/NUnit/MSTest, and central packages. DO NOT USE to only author tests in an already-wired project (code-testing), run tests, migrate, or correct MSTest syntax/configuration without changing project or CI files (writing-mstest-tests).
We split this skill into the rules it gives an agent
16 rules. About 0 are common, 9 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈9
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 21
Create the smallest missing test container or repair only the missing wiring.
- Very specific: line 33
Before applying it, require its frontmatter to declare core: dotnet-test/scaffold-dotnet-test-project, binding-revision: "1", and mode: …
- Distinctive: line 61
No-op is a required outcome: If the suitable project, production reference, and requested entry-point registration already exist, make zero …
- Distinctive: line 63
Do not add or remove a smoke test, normalize the project, recreate packages, or edit a baseline/snapshot copy.
- Very specific: line 70
Start from the task's current working directory.
- Distinctive: line 83
Read only enough to determine:
- Distinctive: line 94
If the user reports that a test project passes directly but solution-level discovery finds nothing, treat that as registration evidence.
- Very specific: line 104
Use a dotnet new template only when its generated framework generation and package style match the repository contract.
- Very specific: line 114
use dotnet add <test-project> reference <production-project> for only the production projects exercised by the requested tests.
- Very specific: line 116
delete template sample files such as UnitTest1.cs, then create a behavior-named test file rather than repurposing the template filename.
- Very specific: line 127
Only when dotnet test uses VSTest command mode to bridge to MTP (SDK 8/9, or SDK 10+ without native MTP mode), preserve or add:
- Distinctive: line 159
No solution artifact: preserve the existing project-oriented workflow.
- Distinctive: line 197
Run the narrowest commands that prove the chosen route:
- Very specific: line 216
Before reporting completion, inspect the final changed-file set.
- Distinctive: line 229
Keep the handoff proportional to the change:
- Distinctive: line 241
Only the requested production scope is referenced and tested.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Scaffold or Repair a .NET Test Project
Create the smallest missing test container or repair only the missing wiring. The goal is test discovery through the repository's real build entry point, not a preferred solution layout.
Repository overlay
For every repository-scoped task where read-only file inspection is allowed,
check .agents/skill-overlays/dotnet-test/scaffold-dotnet-test-project.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.
Before applying it, require its frontmatter to declare
core: dotnet-test/scaffold-dotnet-test-project, binding-revision: "1", and
mode: extend. If any value is missing or different, report the mismatch and
continue using this skill's portable guidance without applying the overlay.
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
and continue with portable guidance, without the overlay, 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.
Route the Request
Inspect the repository before editing, then choose exactly one path:
| Repository state | Action | Do not do |
| No suitable test project | Create one bounded project, reference the production project, and register it | Create a project per source project |
Test project exists but lacks the required ProjectReference | Add only that reference and verify direct plus entry-point execution | Scaffold another project or rewrite tests |
Test project passes directly but is absent from .sln, .slnx, or .slnf | Register the existing project in the exact entry point CI uses | Recreate the project or switch solution formats |
| Suitable project, reference, and requested entry point are already correct | Leave the workspace unchanged; use code-testing if test methods are requested | Normalize or replace working files |
An existing project is suitable when its target framework can reference the production project and its purpose matches the requested layer. A different preferred name is not a reason to create a duplicate.
No-op is a required outcome. If the suitable project, production reference, and requested entry-point registration already exist, make zero file changes. Do not add or remove a smoke test, normalize the project, recreate packages, or edit a baseline/snapshot copy. Report the existing paths and stop.
Workflow
1. Establish the repository contract
Start from the task's current working directory. The skill context's Base
directory is where these instructions live, not the user's repository. Never
search parent temporary directories or treat the skill installation as the
workspace. If the expected files are not visible, confirm the current directory
before concluding that a project is absent.
Anchor every edit and validation command to the repository path named by the user or established from the current directory. If similarly named fixtures, solutions, or copied trees exist, do not edit or validate one as a substitute for the requested tree. Before changing a solution artifact, record its exact path; after changing it, list that same artifact immediately and require the test project to appear before proceeding.
Read only enough to determine:
- the production project and requested test scope;
- the command and
.sln,.slnx,.slnf, or project graph used by CI; - whether a suitable test project exists, what it references, and where it is registered;
- the neighboring test framework, runner, target framework, nullable and implicit-usings conventions; and
- whether package or SDK versions come from
Directory.Packages.props,Directory.Build.props,global.json, or an MSBuild SDK declaration.
If the user reports that a test project passes directly but solution-level discovery finds nothing, treat that as registration evidence. Inspect the entry point before considering project creation.
2. Create only when the project is absent
Choose one test project for the narrowest requested production project. Follow, in order, the user's explicit framework choice, neighboring test projects, repository-wide package/SDK conventions, then a standard SDK template.
Use a dotnet new template only when its generated framework generation and
package style match the repository contract. Inspect template availability
before creation. In particular, generic dotnet new xunit commonly emits xUnit
2 packages; for a centrally managed xunit.v3 repository, use a repository or
installed xUnit v3 template, or create the minimal SDK project directly. Never
generate versioned xUnit 2 references and then rewrite them into xUnit v3.
Then:
- align target framework, nullable, implicit usings, runner, and package style;
- use
dotnet add <test-project> reference <production-project>for only the production projects exercised by the requested tests; - delete template sample files such as
UnitTest1.cs, then create a behavior-named test file rather than repurposing the template filename; and - omit package versions when central package management supplies them.
For xUnit v3 projects using the MTP runner, preserve or add executable output in both command modes, and retain the repository's framework runner opt-in:
<OutputType>Exe</OutputType>Only when dotnet test uses VSTest command mode to bridge to MTP (SDK 8/9,
or SDK 10+ without native MTP mode), preserve or add:
<TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport>For SDK 10+ native MTP mode selected by global.json test.runner, do not add
the compatibility property; remove an explicit bridge setting when configuring
native mode. Keep executable output and the MTP runner enabled.
OutputType=Exe alone proves only the self-hosted runner path, not discovery by
the repository's dotnet test command. Verify the exact command mode and
entry-point execution as described in run-tests: native MTP uses --project
or --solution with direct MTP arguments; VSTest-mode MTP uses a positional
path and passes MTP arguments after --.
3. Repair only the missing edge when the project exists
- Missing production reference: use
dotnet add <test-project> reference <production-project>, inspect the resulting project, and leave every other project element plus all test source files unchanged. Compare the project before and after so the addedProjectReferenceis the only semantic change. - Missing
.slnor.slnxregistration: rundotnet sln <entry-point> add <test-project>, then immediately rundotnet sln <entry-point> listagainst that exact path. If the project is absent, the repair has not happened; do not validate a sibling solution or report success. - Missing
.slnfregistration: add the existing project to its underlying solution if necessary, then include that same project path in the filter. If the underlying solution already contains it, edit only the filter. - Multiple solution artifacts: modify only the one named by the user or invoked by CI. Do not substitute an easier format.
- No solution artifact: preserve the existing project-oriented workflow. Do not create a solution for aesthetics.
4. Add only the requested smoke behavior
For a newly created project, replace template examples with the smallest smoke suite the user requested. Each test must invoke a real production symbol and assert a concrete deterministic result without network, wall-clock, process, or real-filesystem dependencies.
For an existing-project wiring repair, do not add, rewrite, rename, or expand tests unless the user explicitly asks for test behavior changes. Registration and test authoring are separate operations.
5. Verify the repaired path
Select direct-project and entry-point commands using
run-tests and
platform-detection. Resolve the project
system, global.json test.runner, and final imported runner, UseVSTest,
TestingPlatformDotnetTestSupport, and OutputType values; do not select
syntax from the SDK version alone.
| Detected mode / platform | Direct-project command | Solution entry-point command |
| Classic non-SDK | Repository's documented build and test-runner command for the test project | Exact repository/CI build and test-runner command; do not substitute dotnet test |
| VSTest mode / VSTest | dotnet test <test-project> | dotnet test <entry-point> |
| VSTest mode / executable MTP bridge, including SDK 10+ | dotnet test <test-project> -- <MTP_OPTIONS> | dotnet test <entry-point> -- <MTP_OPTIONS> |
SDK 10+ native MTP mode selected by test.runner=Microsoft.Testing.Platform | dotnet test --project <test-project> <MTP_OPTIONS> | dotnet test --solution <entry-point> <MTP_OPTIONS> |
MTP options are optional; when none are needed, omit both <MTP_OPTIONS> and
the bridge separator. Keep dotnet/MSBuild options before -- in bridge mode;
native MTP options are direct arguments, never after --. These are command
shapes, not replacements for a repository script or a project-oriented CI
entry point. Preserve the exact configured entry point and report incompatible
runner/bridge/output wiring rather than switching runners to obtain a green
result.
Run the narrowest commands that prove the chosen route:
| Route | Required evidence |
| Newly created project | Mode-appropriate direct-project test command, the exact entry-point command CI uses, and registration listing. If the entry point is a .slnf/.slnx containing tests, run the mode-appropriate test command on that artifact rather than proving only that it builds. |
| Missing reference | Targeted project test plus the exact solution/root test command requested |
Missing .sln/.slnx registration | Listing and the mode-appropriate test command for that exact artifact; never use another solution as a fallback |
Missing .slnf entry | Inspect the filter entry and run the exact CI filter build command; do not prepend a deliberately failing alternate command |
| Already correct/no-op | Structural inspection of the existing reference and registration. Unless execution was requested, do not run tests merely to prove a no-op because that creates bin/obj and weakens byte-for-byte cleanliness evidence. |
Inspect the repository's command before adding switches. Do not prepend a
speculative --no-restore attempt or hide alternatives in command-a ||
command-b; run the configured entry-point command whose clean exit is the
evidence.
For every wiring repair, invoke the exact validation command directly and preserve its exit status. Reading generated files, a grader script, or a later build is not a substitute for observing that command complete successfully.
Before reporting completion, inspect the final changed-file set. Remove only
bin/obj or equivalent build artifacts created by this task when they were
absent beforehand and are not intentionally tracked; never remove pre-existing
artifacts. Preserve the passing command's complete result so the handoff can
state the exact entry point and discovered test count.
For a no-op, inspect rather than rewrite and report the existing paths. A green
dotnet build is not test-discovery evidence. If validation is blocked, report
the exact failing command and first actionable error; never describe an unrun or
failed command as successful.
Output
Keep the handoff proportional to the change:
| Requirement | Evidence |
| Project created, reused, or repaired | Test project path and chosen route |
| Production reference | Referenced .csproj, or why no change was needed |
| Build registration | Exact .sln/.slnx/.slnf entry or project workflow |
| Test discovery | Passing harness-level command and discovered test |
Completion Checks
- Existing projects were checked before creation.
- Only the requested production scope is referenced and tested.
- Framework, runner, target framework, and central package conventions remain intact.
- Template samples are removed from a newly created project.
- Existing test code is untouched for a wiring-only repair.
- The exact repository entry point discovers and runs the test project.
Trending
Quiet since September.about the whole repository
Who's talking about microsoft/testfx
- Stack Overflow“App.config not being loaded in .Net Core MSTests project”Stack Overflow · Feb 24, 2019 · 35 votes
- Stack Overflow“Visual Studio Test Explorer doesn't run tests after changes”Stack Overflow · Dec 21, 2022 · 31 votes
- Stack Overflow“DataTestMethod vs TestMethod”Stack Overflow · Dec 3, 2019 · 19 votes
- Stack Overflow“ConfigurationManager.AppSettings is always empty”Stack Overflow · May 5, 2020 · 17 votes
- dotnet/sdk“[Proposal]: Add Microsoft.NET.Sdk.Testing”GitHub · Jun 7, 2025 · 10 reactions
The biggest 5 of 68 mentions linking to the repository that our crawl found. Each line is their own headline.
See all 68
Talked about on GitHub and Stack Overflow (68 times).
On GitHub · 41
- Jun 7, 2025[Proposal]: Add Microsoft.NET.Sdk.Testing — dotnet/sdksays it tested it10 reactions · 15 comments
- Feb 4, 2025Dependabot job fails due to attempt to update packages referenced via an MSBuild SDK — dependabot/dependabot-core9 reactions · 13 comments
- Feb 22, 2024Microsoft Testing Platform for xUnit — xunit/visualstudio.xunitsays it tested it6 reactions · 19 comments
- Dec 3, 2018DataTestMethod vs TestMethod — microsoft/testfx-docs6 reactions · 4 comments
- Feb 19, 2024Microsoft Testing Platform for NUnit — nunit/nunit3-vs-adaptersays it tested it5 reactions · 1 comment
36 more on GitHub
- Dec 19, 2023Arcade should opt into `BuildWithNetFrameworkHostedCompiler` by default — dotnet/arcade5 reactions · 18 comments
- Nov 24, 2025Native support for Microsoft.Testing.Platform? — danielpalme/ReportGeneratorsays it tested it4 reactions · 3 comments
- Oct 31, 2025Selecting test runner without global.json — dotnet/sdk3 reactions · 2 comments
- Jul 15, 2025[Analyzer Proposal]: Don't use `stringBuilder.Append(new string(c, repeatCount))` — dotnet/runtime3 reactions · 3 comments
- Jul 13, 2025Allow `dotnet test --list-tests json` — dotnet/sdk3 reactions · 7 comments
- Jul 9, 2025Improve output of `dotnet test` with MTP — dotnet/sdk3 reactions · 6 comments
- Jan 30, 2024Support for the new test runner — nunit/nunit3 reactions · 3 comments
- Oct 17, 2017[ExcludeFromCodeCoverageAttribute] should be applicable to assemblies — dotnet/runtime3 reactions · 12 comments
- Sep 2, 2026chore(deps): update mstest to 4.4.0 — thomhurst/TUnit2 reactions · 3 comments
- Dec 17, 2025[MTP] Cannot switch off terminal logger when building during dotnet test — dotnet/sdk2 reactions
- Oct 8, 2025Bump MSTest.TestFramework from 3.11.0 to 4.0.0 — files-community/Files2 reactions · 1 comment
- May 27, 2025Dependabot Ignores Configuration File Settings in latest Version — dependabot/dependabot-core2 reactions · 7 comments
- May 20, 2025Add `-vs` and `-vscode` to build scripts — dotnet/arcade2 reactions · 8 comments
- Mar 14, 2025Add template for dotnet.config to dotnet new — dotnet/sdk2 reactions · 2 comments
- Jan 16, 2024An Allure adapter for MSTest — allure-framework/allure-csharp2 reactions · 2 comments
- Apr 10, 2018Added docs for dynamic data display name — microsoft/testfx-docs2 reactions · 1 comment
- Sep 3, 2026chore(deps): update microsoft.testing — thomhurst/TUnit1 reaction · 3 comments
- Mar 16, 2026Bump dotnet-sdk from 10.0.103 to 10.0.201 — jas88/FAnsiSql1 reaction
- Mar 16, 2026Bump dotnet-sdk from 10.0.103 to 10.0.201 — jas88/libarchive.net1 reaction
- Mar 16, 2026Bump dotnet-sdk from 10.0.103 to 10.0.201 — jas88/RDMP1 reaction
- Mar 16, 2026sdk(deps): Bump dotnet-sdk from 10.0.103 to 10.0.201 — jas88/CsvHandler1 reaction · 1 comment
- Mar 16, 2026chore(deps): bump dotnet-sdk from 10.0.103 to 10.0.201 — jas88/SharpDicom1 reaction
- Mar 16, 2026Bump dotnet-sdk from 10.0.103 to 10.0.201 — jas88/nccid1 reaction
- Mar 15, 2026chore(deps): bump dotnet-sdk from 10.0.103 to 10.0.201 — jas88/filestats1 reaction
- Mar 15, 2026Bump dotnet-sdk from 10.0.103 to 10.0.201 — jas88/MCPsharp1 reaction
- Mar 15, 2026Bump dotnet-sdk from 10.0.103 to 10.0.201 — jas88/SynthEHR1 reaction
- Mar 15, 2026Bump dotnet-sdk from 10.0.103 to 10.0.201 — jas88/TypeGuesser1 reaction
- Mar 15, 2026Bump dotnet-sdk from 10.0.103 to 10.0.201 — jas88/LineReader1 reaction
- Mar 15, 2026Bump dotnet-sdk from 10.0.103 to 10.0.201 — jas88/DicomTypeTranslation1 reaction
- Mar 12, 2026Bump dotnet-sdk from 10.0.103 to 10.0.201 — jas88/dcm2csv1 reaction
- Mar 11, 2026chore(deps): bump dotnet-sdk from 10.0.103 to 10.0.200 — jas88/PACSify1 reaction
- Mar 7, 2025Use Microsoft Testing Platform — martincostello/alexa-london-travelsays it tested it1 reaction · 3 comments
- Feb 17, 2025Bump the mstest group across 1 directory with 2 updates — kusl/fluentassertions1 reaction · 9 comments
- May 25, 2026Bump MSTest.TestAdapter and MSTest.TestFramework — fluentassertions/fluentassertions0 reactions · 8 comments
- May 18, 2026Bump the mstest group with 2 updates — fluentassertions/fluentassertions0 reactions · 3 comments
- May 11, 2026Bump MSTest.TestAdapter and MSTest.TestFramework — fluentassertions/fluentassertions0 reactions · 4 comments
On Stack Overflow · 27
- Feb 24, 2019App.config not being loaded in .Net Core MSTests project35 votes
- Dec 21, 2022Visual Studio Test Explorer doesn't run tests after changes31 votes
- Dec 3, 2019DataTestMethod vs TestMethod19 votes
- May 5, 2020ConfigurationManager.AppSettings is always empty17 votes
- Dec 4, 2020The type or namespace name 'PrivateObject' could not be found6 votes
22 more on Stack Overflow
- Nov 2, 2018'TestContext' does not contain a definition for 'DataRow'5 votes
- Jun 15, 2019Get TestResult in MSTest TestCleanup in C#4 votes
- Nov 14, 2024Does a [TestMethod] have to be public? What consequences are there if it isn't?3 votes
- Aug 26, 2020'Inconclusive' tests are reported as 'not run' by Azure DevOps3 votes
- Sep 18, 2018Guidance for running tests using MSTest v1 in Visual Studio 2017 15.8.13 votes
- Nov 29, 2017Long running unit test marked as passed fails TFS build - Object 'xxx.rem' has been disconnected or does not exist at the server.**3 votes
- Jun 25, 2021use PrivateObject in .net 5 from nugget MSTest.TestFramework2 votes
- Jan 7, 2020MS Test V2 - ClassInitialize behavior when fail2 votes
- Oct 30, 2019Test Methods and Test Class in compiled DLL2 votes
- Jan 15, 2019Use configuration file to specify connection string to define a data source in unit test2 votes
- May 2, 2017Where is MSTest V22 votes
- Oct 15, 2022How to unit test private method in .Net Core application which does not support "PrivateObject"1 vote
- Oct 5, 2022Only first DataRow gets executed in MSTest1 vote
- Feb 4, 2021MS Tests DataTestMethod Timeout for a single test1 vote
- Feb 13, 2020PrivateObject class not found in .Net Core 2.01 vote
- Jan 4, 2020MsTest TestCleanup method not called when an unhandled exception is thrown1 vote
- May 3, 2019Where do I find TestContext.AddResultFile()?1 vote
- Apr 24, 2017Inherited test class from generic base is ignored in MSTest1 vote
- Aug 20, 2025Use MSTest.Sdk for TestHelper0 votes · 1 answer
- Mar 9, 2022Test results are published correctly but not reflected in pipeline Results - Azure devops (Yaml)0 votes
- Dec 22, 2021Testing with empty string using DataRow in MsTestV20 votes
- Feb 6, 2018Why does Visual Studio Always pull in the latest version Unit Test Framework within a solution when older versions are already included0 votes
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- rodri-oliveira-dev/complexity-analyzers★ 4same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository62 other files it gives its agents.
- AGENTS.mdAGENTS.md
- eng/common/AGENTS.mdAGENTS.md
- .github/copilot-instructions.mdCopilot instructions
- assertion-qualitySkill
- binlog-failure-analysisSkill
- binlog-generationSkill
- build-parallelismSkill
- build-perf-baselineSkill
- build-perf-diagnosticsSkill
- check-bin-obj-clashSkill
- code-testing-agentSkill
- code-testing-extensionsSkill
- code-testingSkill
- copy-to-output-directorySkill
- coverage-analysisSkill
- crap-scoreSkill
- csharp-expertSkill
- csharp-refactoringSkill
- curation-exceptionsSkill
- detect-static-dependenciesSkill
- directory-build-organizationSkill
- eliminate-redundant-restoresSkill
- eval-performanceSkill
- extension-pointsSkill
- filter-syntaxSkill
- find-untested-sourcesSkill
- generate-testability-wrappersSkill
- grade-testsSkill
- including-generated-filesSkill
- incremental-buildSkill
- item-managementSkill
- migrate-static-to-wrapperSkill
- msbuild-antipatternsSkill
- msbuild-modernizationSkill
- msbuild-serverSkill
- msbuildSkill
- mtp-hot-reloadSkill
- platform-detectionSkill
- property-patternsSkill
- resolve-project-referencesSkill
- run-testsSkill
- setup-local-sdkSkill
- target-authoringSkill
- testability-obstacleSkill
- test-analysis-extensionsSkill
- test-anti-patternsSkill
- test-gap-analysisSkill
- test-smell-detectionSkill
- test-taggingSkill
- test-value-evidenceSkill
- troubleshoot-binlog-mcpSkill
- writing-mstest-testsSkill
- agentic-workflowsSkill
- behavior-preserving-refactorSkill
- code-reviewSkill
- feature-deliverySkill
- post-release-activitiesSkill
- session-delivery-hygieneSkill
- testfx-acceptance-validationSkill
- testfx-localization-validationSkill
- The first 60 shown.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

