Clarify MSTest.Sdk incompatibility with ASP.NET Core (Microsoft.NET.Sdk.Web)#54554
Conversation
|
|
||
| Alternatively, you can enable MSTest runner by adding the `EnableMSTestRunner` property and setting `OutputType` to `Exe` in your project file. You also need to ensure that you're using `MSTest 3.2.0` or newer. We strongly recommend you update to the latest MSTest version available. | ||
| > [!NOTE] | ||
| > Because `MSTest.Sdk` replaces `Microsoft.NET.Sdk`, it isn't compatible with projects that require a different project SDK. For example, ASP.NET Core integration test projects that require `Microsoft.NET.Sdk.Web` can't use `MSTest.Sdk`. |
There was a problem hiding this comment.
Have we tried one of the following?
<Project Sdk="Microsoft.NET.Sdk.Web">
<Import Project="Sdk.props" Sdk="MSTest.Sdk" />
// ...
<Import Project="Sdk.targets" Sdk="MSTest.Sdk" />
</Project>or
<Project Sdk="MSTest.Sdk">
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk.Web" />
// ...
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk.Web" />
</Project>to see if that works? And if it does work, do we want to make that recommendation?
And if it doesn't work, is there anything that MSTest.Sdk could adjust to make that work?
There was a problem hiding this comment.
Hey @Youssef1313 :)
I'm really trying to just correct the issue at hand which is there is some ambiguity as to when you can actually take the prescribed course of replacing the SDK entry. If you can test and suggest a different suggestion in the article, that would be great! I did just reedit the Copilot suggestions and I think it's clearer this time. So please re-review.
There was a problem hiding this comment.
I tested both of your variants empirically (net10.0, MSTest.Sdk 3.10.4, ASP.NET Core reference + a real [TestMethod] run). Results differ, which is interesting:
Variant 1 — top-level Microsoft.NET.Sdk.Web, manually import MSTest.Sdk:
<Project Sdk="Microsoft.NET.Sdk.Web">
<Import Project="Sdk.props" Sdk="MSTest.Sdk" />
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>
<Import Project="Sdk.targets" Sdk="MSTest.Sdk" />
</Project>Works — restores, builds, references WebApplication.CreateBuilder(), and the MSTest runner runs the tests (Passed! Failed: 0, Passed: 2). But it emits MSB4011 duplicate-import warnings, because both Microsoft.NET.Sdk.Web and MSTest.Sdk import Microsoft.NET.Sdk:
warning MSB4011: "...\Microsoft.NET.Sdk\Sdk\Sdk.props" cannot be imported again.
It was already imported at "...\Microsoft.NET.Sdk.Web\Targets\Sdk.Server.props".
This subsequent import will be ignored.
Variant 2 — top-level MSTest.Sdk, manually import Microsoft.NET.Sdk.Web:
<Project Sdk="MSTest.Sdk">
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk.Web" />
...
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk.Web" />
</Project>Fails to compile (deterministic):
error CS0234: The type or namespace name ''TestingPlatformBuilderHook'' does not exist
in the namespace ''Microsoft.VisualStudio.TestTools.UnitTesting''
(SelfRegisteredExtensions.cs, generated by the MSTest runner)
Plus the same MSB4011 warnings. The import ordering here means the Web SDK''s bottom targets interfere with the runner setup that MSTest.Sdk''s bottom import performs, so the generated runner bootstrap can''t resolve its hook type.
So: Variant 1 works but is warning-noisy; Variant 2 is broken. Given that, I don''t think we should recommend either in the article as-is — the clean, warning-free path remains "keep the Web SDK as the outer SDK and add the MSTest references + EnableMSTestRunner manually", which is what the PR now does.
On your last question — "is there anything MSTest.Sdk could adjust to make that work?" — yes, I think so, and I filed microsoft/testfx#9562 to explore guarding/conditioning our base-SDK import so Variant 1 is warning-free (and ideally so a layering order works cleanly). I''ll add these Variant 1/Variant 2 findings to that issue.
Clarify compatibility of MSTest.Sdk with project SDKs and provide instructions for manual configuration.
There was a problem hiding this comment.
Pull request overview
This PR clarifies how to enable Microsoft.Testing.Platform (MTP) in MSTest projects by explaining that MSTest.Sdk replaces the project SDK, which makes it unsuitable for projects that must use a different top-level SDK (for example, Microsoft.NET.Sdk.Web for ASP.NET Core integration tests). It also tightens guidance on when to use the manual configuration approach.
Changes:
- Rewrites the “Enable MTP in an MSTest project” intro to be more direct and explicit about
MSTest.Sdkreplacing the project SDK. - Adds a NOTE callout explaining why
MSTest.Sdkshouldn’t be used when a project needs a different SDK (example: ASP.NET Core). - Rewrites the “Alternatively” guidance to scope it to non-
Microsoft.NET.Sdkprojects and explain the manual setup path.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
@Evangelink Can you review? |
Evangelink
left a comment
There was a problem hiding this comment.
Reviewed the change and verified the core technical claim against the actual MSTest.Sdk source and by building a real project. Overall this is a solid, well-motivated clarification. A few suggestions inline, plus two repo-level notes:
ai-usagefrontmatter (repo guideline): the file''s frontmatter has noai-usagekey, and this change was authored by the Copilot agent. Per the .NET docs guidelines, AI-assisted Markdown should disclose it — please addai-usage: ai-assisted. (Frontmatter isn''t in the diff, so I couldn''t attach this inline.)- Follow-up filed on testfx: I opened microsoft/testfx#9562 to explore making the mixed-SDK scenario warning-free (conditional/skip base import), since today combining
MSTest.Sdkwith another base SDK by hand works but emitsMSB4011.
Verification notes (for reviewers): MSTest.Sdk hard-imports Microsoft.NET.Sdk in both Sdk.props.template and Sdk.targets, with no base-SDK override — so the incompatibility described here is real and accurate. I also confirmed that manually importing both Microsoft.NET.Sdk.Web and MSTest.Sdk (via <Import .../> rather than the Sdk attribute) does build and run tests, but produces MSB4011 duplicate-import warnings, so it''s correctly not recommended here.
| > [!NOTE] | ||
| > `MSTest.Sdk` works only when your project can use `Microsoft.NET.Sdk` as its base SDK. If your project requires a different SDK, don't replace the `<Project Sdk="...">` value with `MSTest.Sdk`. | ||
| > | ||
| > For example, ASP.NET Core integration test projects use `Microsoft.NET.Sdk.Web`. `MSTest.Sdk` derives from `Microsoft.NET.Sdk`, so it doesn't import the ASP.NET Core SDK targets that `Microsoft.NET.Sdk.Web` provides. |
There was a problem hiding this comment.
This is stated too broadly. Most ASP.NET Core integration test projects use Microsoft.NET.Sdk (with WebApplicationFactory + the Microsoft.AspNetCore.Mvc.Testing package, which pulls in the framework reference automatically) — only some opt into Microsoft.NET.Sdk.Web. Since this example is the whole justification for the note, consider softening to something like "Some ASP.NET Core integration test projects use Microsoft.NET.Sdk.Web." to avoid implying it''s the norm.
| > | ||
| > For example, ASP.NET Core integration test projects use `Microsoft.NET.Sdk.Web`. `MSTest.Sdk` derives from `Microsoft.NET.Sdk`, so it doesn't import the ASP.NET Core SDK targets that `Microsoft.NET.Sdk.Web` provides. | ||
|
|
||
| If your project uses an SDK other than `Microsoft.NET.Sdk`, keep that SDK, and configure MSTest manually. Add the `EnableMSTestRunner` property and set `OutputType` to `Exe` in your project file. Then add the MSTest references that your project requires. Ensure that you're using MSTest 3.2.0 or newer, and update to the latest MSTest version available. The following example uses `Microsoft.NET.Sdk`, but the same properties work with other project SDKs (for example, `Microsoft.NET.Sdk.Web`). |
There was a problem hiding this comment.
Two thoughts on this paragraph:
-
Add reassurance for the common case. For a test project it''s quite unlikely you''d need a base SDK other than ours —
MSTest.Sdk(or plainMicrosoft.NET.Sdk) covers almost every scenario. Worth a sentence so readers don''t over-think it, e.g. "For most test projects you won''t need a base SDK other thanMSTest.Sdk; this only applies in rarer cases (such as ASP.NET Core integration tests) where the project genuinely requires a different SDK." -
Scope nuance: by scoping this to "If your project uses an SDK other than
Microsoft.NET.Sdk", a reader on a plainMicrosoft.NET.Sdkproject who simply prefers manual configuration (noMSTest.Sdk) may think this section no longer applies to them. Consider "You can also configure MSTest manually — for example, when your project requires a different base SDK."
FYI I verified the combined-SDK path empirically: manually importing both Microsoft.NET.Sdk.Web and MSTest.Sdk does build and run tests, but emits MSB4011 duplicate-import warnings because both import Microsoft.NET.Sdk. So the manual-references approach you recommend here is the clean one — tracked upstream in microsoft/testfx#9562.
The "Enable MTP in an MSTest project" section didn't explain that
MSTest.SdkreplacesMicrosoft.NET.Sdkas the project SDK—making it incompatible with ASP.NET Core integration test projects that requireMicrosoft.NET.Sdk.Web. The "alternatively" paragraph also didn't make clear when to use manual configuration over the SDK approach.Changes
MSTest.SdkreplacesMicrosoft.NET.Sdkas the project SDK with MTP enabled by default.MSTest.Sdkisn't compatible with projects requiring a different SDK, withMicrosoft.NET.Sdk.Web(ASP.NET Core) as the concrete example.Microsoft.NET.Sdk. Removed the "We strongly recommend" phrasing per style guide.Internal previews