Arcade currently maintains five parallel test-runner code paths in
src/Microsoft.DotNet.Arcade.Sdk/tools/ (XUnit, XUnitV3, MSTest,
VSTest, Microsoft.Testing.Platform) plus two parallel Helix work-item
generators in src/Microsoft.DotNet.Helix/Sdk/ (xunit-runner /
CreateXUnitWorkItems and mtp-runner / CreateMTPWorkItems).
Most of that surface area predates Microsoft.Testing.Platform (MTP):
- xUnit v3 defaults to MTP and produces a self-hosting test
executable when paired with
Microsoft.Testing.Platform.MSBuild. - MSTest 4.x defaults to MTP via
MSTest.Sdk/MSTestmetapackage. - NUnit, TUnit, and other frameworks ship MTP runners.
dotnet testis now MTP-aware (TestingPlatformDotnetTestSupport) and in .NET 10 thedotnet test --use-testing-platformexperience is the official orchestrator for MTP-based projects.- VSTest is in maintenance mode; the testfx team has stated that future investment is on MTP.
The legacy paths therefore exist purely as compatibility surface. Each one
adds property names that have to be documented and supported, complicates
the Test target dispatch, and ships duplicated logger / TRX wiring that
MTP gives us for free.
Reduce the Arcade test-execution surface to:
- One runner targets file in the Arcade SDK that invokes MTP exes
directly (already present:
tools/Microsoft.Testing.Platform/Microsoft.Testing.Platform.targets). - One thin
dotnet testwrapper for projects that have not yet migrated to MTP — used only when the project is not a Testing Platform application. - One Helix work-item generator
(
CreateMTPWorkItems) replacing both the legacyCreateXUnitWorkItemsflow and any framework-specific work-item generators.
Helix orchestration itself (SendHelixJob, queue selection, correlation
payloads, EnableHelixJobMonitor, XHarness for iOS/Android/WASM, test
retry, AzDO test-run lifecycle) is out of scope — those are Arcade's
genuine value-add and are independent of which runner runs the test.
This is staged so each phase is independently revertable.
- Add this document.
- Emit MSBuild warnings when a project opts into a path that we intend to
remove:
- Setting
UsingToolXUnit(any value) — property is already documented as deprecated inDefaultVersions.propsbut emits no warning. - Setting
UseVSTestRunner=true. - Including
XUnitProjectitems in a Helix project (useMTPProjectinstead — see the Helix Sdk readme).
- Setting
- Delete the orphaned
xunit-reporter.pyHelix Python script which is already self-marked as deprecated and is no longer invoked from any Arcade target.
No behavior changes for repos that do not set the deprecated properties.
- Default
UseMicrosoftTestingPlatformRunner=trueis already in place for xUnit v3 (XUnitV3.targets). Audit downstream repos via arcade-validation to confirm there are no remaining consumers relying on the VSTest path. - Default
EnableMSTestRunner=truefor MSTest projects, with an opt-out for repos that still depend on VSTest-specific loggers / runsettings features. - Remove
Microsoft.NET.Test.Sdkfrom the implicit reference set for MTP projects (already conditional onIsTestingPlatformApplication != trueinTests.props; ensure that flag is reliably set for every MTP path).
- Delete
tools/XUnit/(XUnit.targetsandXUnit.Runner.targets). xUnit v2 is in maintenance upstream; v3 has been the Arcade recommendation since #15671. - Repos still on v2 can pin to an older Arcade SDK or set
TestRunnerName=XUnitand import their own targets.
- Replace
XUnitV3.Runner.targets,VSTest.targets, and the runner portion ofMSTest.targetswith a singleRunTeststarget that:- for MTP projects (
IsTestingPlatformApplication=true), execs the self-hosting test app with MTP reporter flags; and - for non-MTP projects, invokes
dotnet testwith standard--logger trx;...arguments.
- for MTP projects (
- Framework-specific
.targetsshrink to package-reference lists only.
- Delete
tools/xunit-runner/(XUnitRunner.props,XUnitRunner.targets,XUnitPublish.targets— the publish helper has already been generalized to_MTPPublishTargetsPath) andCreateXUnitWorkItems.cs.MTPProjectalready covers xUnit v3, MSTest 4, NUnit, and TUnit. - Drop the related
XUnitProject,XUnitPublishTargetFramework,XUnitRuntimeTargetFramework,XUnitRunnerVersion, andXUnitArgumentsproperties from the SDK and the SendingJobsToHelix doc.
Tests.targets' inner/outer loops overTestArchitectures×TargetFrameworksexist to feed runner CLIs. OnceRunTestsis justdotnet test, the .NET SDK's per-TFM dispatch covers the TFM axis. The architecture axis (x86/x64 multiplexing of a single binary on .NET Framework) is Arcade-specific and stays — but the wrapper shrinks to roughly 20 lines.
| Area | Files removed | LoC removed | Public properties / items removed |
|---|---|---|---|
| Arcade SDK runner targets | XUnit v2 dir, VSTest.targets, two *.Runner.targets |
~400 | UseVSTestRunner, UsingToolXUnit, TestRunnerName=XUnit|VSTest |
| Helix Sdk legacy xUnit | xunit-runner/, CreateXUnitWorkItems.cs, xunit-reporter/ |
~600 | XUnitProject, XUnitPublishTargetFramework, XUnitRuntimeTargetFramework, XUnitRunnerVersion, XUnitArguments, EnableXUnitReporter |
| Total | ~10 files | ~1000 LoC | 8 properties + 1 item group |