Clean up xUnit from the SDK test harness#55059
Merged
Merged
Conversation
…y.Build.targets Replace the per-project <Using Include="Microsoft.NET.TestFramework.*" /> blocks (repeated across ~34 test projects, plus three GlobalUsings.cs files) with a single ProjectReference-driven ItemGroup in test/Directory.Build.targets that applies the five framework namespaces to any project referencing the SDK test framework (the legacy Microsoft.NET.TestFramework or its MSTest counterpart). The two framework projects themselves reference neither and keep their own local usings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…MSTest projects out of Arcade's xUnit Migrate Microsoft.DotNet.HotReload.Test.Utilities (the last SDK-owned xUnit v3 test helper) to MSTest: map Xunit.Assert/XunitException/NotEqualException to MSTest Assert/AssertFailedException, bind ITestOutputHelper to Microsoft.NET.TestFramework, delete the unused WatchSdkTest, and reference Microsoft.NET.TestFramework.MSTest instead of the legacy framework (dropping xunit.v3.extensibility.core + Xunit.Combinatorial). dotnet-watch.Tests, its only consumer, then drops its xunit.v3 package references and its DualOutputHelper no longer needs to bridge Xunit.ITestOutputHelper. With the legacy framework no longer leaking in transitively, the Microsoft.NET.TestFramework.MSTest reference is exposed as global,MSTestFramework so the previously-aliased types resolve. Separately, set UsingToolXUnit=false for MSTest.Sdk projects so Arcade stops injecting the unused xUnit v2 package set (xunit.core/assert/runner.console/runner.visualstudio) into every MSTest test output; MSTest projects run on Microsoft.Testing.Platform. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ComponentMocks and Msbuild.Tests.Utilities use no xUnit and no framework types directly, so repoint them from the legacy (xUnit v3) Microsoft.NET.TestFramework to the MSTest counterpart. With ComponentMocks no longer compiled against the legacy framework, dotnet.Tests and Microsoft.DotNet.PackageInstall.Tests can drop their legacy framework ProjectReference and the RemoveConflictingTestFrameworkReference (CS0433) workaround. This removes the legacy framework / xUnit v3 from all of these projects. The legacy framework now remains referenced only by the vendored NetAnalyzers tests and the dotnet/templating-owned Microsoft.TemplateEngine.Cli.UnitTests, both out of scope here. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The vendored Microsoft.CodeAnalysis.NetAnalyzers.UnitTests imports test/Directory.Build.targets and is an xUnit (non-MSTest) test project that relied on the global Xunit using the centralization commit dropped, breaking compilation with CS0246 (Fact/Theory not found). Re-add the Xunit using under the IsTestProject and non-MSTest condition (MSTest projects must not get it, as it clashes with MSTest's Assert). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Removes remaining xUnit dependencies from the SDK-owned test harness by centralizing Microsoft.NET.TestFramework* global usings, migrating the last SDK-owned xUnit-coupled helper library to MSTest, and preventing Arcade tooling from injecting unused xUnit v2 packages into MSTest.Sdk test outputs.
Changes:
- Centralize
Microsoft.NET.TestFramework*global usings intest/Directory.Build.targetsbased onProjectReferencedetection, and remove duplicated per-project<Using>items /GlobalUsings.csfiles. - Migrate
Microsoft.DotNet.HotReload.Test.Utilitiesanddotnet-watch.Testsoff xUnit v3 types/packages (assertions + output helper bridging). - Drop remaining SDK-owned consumers of the legacy xUnit-coupled
Microsoft.NET.TestFrameworkand remove now-unneeded CS0433 workaround targets; opt MSTest.Sdk projects out of Arcade’s xUnit tooling injection.
Show a summary per file
| File | Description |
|---|---|
| test/trustedroots.Tests/trustedroots.Tests.csproj | Remove redundant Microsoft.NET.TestFramework <Using> now provided centrally. |
| test/sdk-tasks.Tests/sdk-tasks.Tests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Msbuild.Tests.Utilities/Msbuild.Tests.Utilities.csproj | Switch from legacy Microsoft.NET.TestFramework to .MSTest reference. |
| test/msbuild.Integration.Tests/msbuild.Integration.Tests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Microsoft.Win32.Msi.Tests/Microsoft.Win32.Msi.Tests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Microsoft.WebTools.AspireService.Tests/Microsoft.WebTools.AspireService.Tests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Microsoft.TemplateEngine.Cli.UnitTests/GlobalUsings.cs | Remove now-unnecessary Microsoft.NET.TestFramework* global usings. |
| test/Microsoft.NET.ToolPack.Tests/GlobalUsings.cs | Delete per-project global usings file now covered by centralized usings. |
| test/Microsoft.NET.Sdk.Razor.Tests/Microsoft.NET.Sdk.Razor.Tests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Microsoft.NET.Sdk.BlazorWebAssembly.AoT.Tests/Microsoft.NET.Sdk.BlazorWebAssembly.AoT.Tests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Microsoft.NET.Restore.Tests/Microsoft.NET.Restore.Tests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Microsoft.NET.Rebuild.Tests/Microsoft.NET.Rebuild.Tests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Microsoft.NET.Publish.Tests/Microsoft.NET.Publish.Tests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Microsoft.NET.Pack.Tests/Microsoft.NET.Pack.Tests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Microsoft.NET.Clean.Tests/Microsoft.NET.Clean.Tests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Microsoft.NET.Build.Tests/GlobalUsings.cs | Delete per-project global usings file now covered by centralized usings. |
| test/Microsoft.NET.Build.Tasks.Tests/Microsoft.NET.Build.Tasks.Tests.csproj | Remove redundant Microsoft.NET.TestFramework <Using> item. |
| test/Microsoft.NET.Build.Extensions.Tasks.Tests/Microsoft.NET.Build.Extensions.Tasks.Tests.csproj | Remove redundant Microsoft.NET.TestFramework <Using> item. |
| test/Microsoft.NET.Build.Containers.IntegrationTests/Microsoft.NET.Build.Containers.IntegrationTests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Microsoft.DotNet.Tools.Tests.ComponentMocks/Microsoft.DotNet.Tools.Tests.ComponentMocks.csproj | Switch from legacy Microsoft.NET.TestFramework to .MSTest reference. |
| test/Microsoft.DotNet.TemplateLocator.Tests/Microsoft.DotNet.TemplateLocator.Tests.csproj | Remove redundant Microsoft.NET.TestFramework <Using> item. |
| test/Microsoft.DotNet.PackageValidation.Tests/Microsoft.DotNet.PackageValidation.Tests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Microsoft.DotNet.PackageInstall.Tests/Microsoft.DotNet.PackageInstall.Tests.csproj | Remove legacy framework reference + CS0433 workaround target + redundant usings. |
| test/Microsoft.DotNet.MSBuildSdkResolver.Tests/Microsoft.DotNet.MSBuildSdkResolver.Tests.csproj | Remove redundant Microsoft.NET.TestFramework <Using> item. |
| test/Microsoft.DotNet.HotReload.Test.Utilities/WatchSdkTest.cs | Remove unused xUnit-based helper base class. |
| test/Microsoft.DotNet.HotReload.Test.Utilities/WatchableApp.cs | Replace xUnit assertions with MSTest assertions. |
| test/Microsoft.DotNet.HotReload.Test.Utilities/TestLogger.cs | Switch output helper type dependency away from xUnit. |
| test/Microsoft.DotNet.HotReload.Test.Utilities/Microsoft.DotNet.HotReload.Test.Utilities.csproj | Switch test framework reference to .MSTest and drop xUnit v3 package refs. |
| test/Microsoft.DotNet.HotReload.Test.Utilities/DebugTestOutputLogger.cs | Switch output helper interface to Microsoft.NET.TestFramework’s. |
| test/Microsoft.DotNet.HotReload.Test.Utilities/AwaitableProcess.cs | Replace xUnit assertions with MSTest assertions. |
| test/Microsoft.DotNet.HotReload.Test.Utilities/AssertEx.cs | Replace xUnit exception types with MSTest assertion failure. |
| test/Microsoft.DotNet.GenAPI.IntegrationTests/Microsoft.DotNet.GenAPI.IntegrationTests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Microsoft.DotNet.Cli.Utils.Tests/Microsoft.DotNet.Cli.Utils.Tests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Microsoft.DotNet.ApiSymbolExtensions.Tests/Microsoft.DotNet.ApiSymbolExtensions.Tests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Microsoft.DotNet.ApiDiff.IntegrationTests/Microsoft.DotNet.ApiDiff.IntegrationTests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Microsoft.DotNet.ApiCompatibility.Tests/Microsoft.DotNet.ApiCompatibility.Tests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Microsoft.DotNet.ApiCompat.IntegrationTests/Microsoft.DotNet.ApiCompat.IntegrationTests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/EndToEnd.Tests/EndToEnd.Tests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/dotnet.Tests/dotnet.Tests.csproj | Remove legacy framework workaround and per-project Microsoft.NET.TestFramework* usings. |
| test/dotnet-watch.Tests/TestUtilities/DualOutputHelper.cs | Remove xUnit output helper bridging; keep MSTest framework adapter. |
| test/dotnet-watch.Tests/dotnet-watch.Tests.csproj | Drop per-project test framework usings and xUnit v3 runtime package refs; adjust aliasing. |
| test/dotnet-new.IntegrationTests/dotnet-new.IntegrationTests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items; keep xUnit-using removals. |
| test/dotnet-MsiInstallation.Tests/dotnet-MsiInstallation.Tests.csproj | Remove redundant Windows-only Microsoft.NET.TestFramework* <Using> items. |
| test/dotnet-format.UnitTests/dotnet-format.UnitTests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/dotnet-aot.Tests/dotnet-aot.Tests.csproj | Remove redundant Microsoft.NET.TestFramework* <Using> items. |
| test/Directory.Build.targets | Add ProjectReference-driven global usings for Microsoft.NET.TestFramework*; keep xUnit global using limited to non-MSTest.Sdk projects. |
| test/Directory.Build.props | Set UsingToolXUnit=false for MSTest.Sdk projects to stop Arcade xUnit v2 injection. |
| test/ArgumentForwarding.Tests/ArgumentForwarding.Tests.csproj | Remove redundant Microsoft.NET.TestFramework <Using> item. |
Copilot's findings
- Files reviewed: 49/49 changed files
- Comments generated: 1
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
Author
|
/ba-g #51530 |
JeremyKuhne
approved these changes
Jun 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up cleanup after the bulk test migration to MSTest.Sdk on MTP (#54976). This removes xUnit from the SDK-owned test harness as far as is responsibly possible and factors out repeated test-project boilerplate. Reviewable as three self-contained commits.
1. Centralize
Microsoft.NET.TestFrameworkglobal usingsThe five
Microsoft.NET.TestFramework.*namespaces were declared as<Using>items in ~34 test.csprojfiles (and threeGlobalUsings.cs). Replaced with a single ProjectReference-drivenItemGroupintest/Directory.Build.targetsthat applies them to any project referencing the SDK test framework (legacy or.MSTest). The two framework projects keep their own local usings.2. Migrate the last SDK-owned xUnit helper + stop Arcade's xUnit injection
Microsoft.DotNet.HotReload.Test.Utilities(xUnit v3) → MSTest:Xunit.Assert/XunitException/NotEqualException→ MSTestAssert/AssertFailedException;ITestOutputHelperbound toMicrosoft.NET.TestFramework; deleted the unusedWatchSdkTest; now referencesMicrosoft.NET.TestFramework.MSTestand dropsxunit.v3.extensibility.core+Xunit.Combinatorial.dotnet-watch.Tests(its only consumer) drops itsxunit.v3.*packages;DualOutputHelperno longer bridgesXunit.ITestOutputHelper. The.MSTestreference is exposed asglobal,MSTestFrameworkso previously-aliased types still resolve once the legacy framework stops leaking in transitively.UsingToolXUnit=falsefor MSTest.Sdk projects so Arcade stops injecting the unused xUnit v2 package set (xunit.core/assert/runner.console/runner.visualstudio) into every MSTest test output — those projects run on Microsoft.Testing.Platform.3. Drop the legacy xUnit framework from SDK-owned consumers
ComponentMocksandMsbuild.Tests.Utilitiesuse no xUnit and no framework types directly, so they're repointed from the legacy (xUnit v3)Microsoft.NET.TestFrameworkto.MSTest. WithComponentMocksno longer compiled against the legacy framework,dotnet.TestsandMicrosoft.DotNet.PackageInstall.Testsdrop their legacyProjectReferenceand theRemoveConflictingTestFrameworkReference(CS0433) workaround.Validation
All touched projects build 0 warnings / 0 errors against the locally-built SDK. Representative MTP runs pass:
dotnet-watch.Tests35/35,PackageInstall.Tests/ToolPackageDownloaderTests50 passed + 2 skipped (heavyComponentMocksusers),dotnet.Tests/LaunchSettingsParserTests9/9. Verified no xUnit assemblies are deployed in the migrated outputs.Intentionally out of scope
Literal "zero xUnit" isn't reachable from this repo; the following are left untouched and still pull in xUnit:
Microsoft.NET.TestFramework— now referenced only by the vendoredMicrosoft.CodeAnalysis.NetAnalyzerstests (Roslyn mirror) and the dotnet/templating-ownedMicrosoft.TemplateEngine.Cli.UnitTests.Microsoft.TemplateEngine.Mocks/TestHelper(xunit.v3.extensibility.core) anddotnet-new.IntegrationTests' runtime-onlyVerify.XunitV3— perAGENTS.md, templating changes belong in dotnet/templating.eng/XUnitV3,test/xunit.runner.json,test/xunit-runner— still drive the remaining xUnit v3 projects above.XUnit-CSharpproject template and the xUnit test-asset fixtures (deliberately xUnit).Once the vendored NetAnalyzers tests and the templating-owned helpers move off xUnit, the legacy
Microsoft.NET.TestFrameworkcan be deleted and…MSTestrenamed to take its place.