Skip to content

Migrate test infrastructure from xUnit v2 to xUnit v3#52930

Draft
MichaelSimons wants to merge 15 commits intodotnet:mainfrom
MichaelSimons:xunit-v3
Draft

Migrate test infrastructure from xUnit v2 to xUnit v3#52930
MichaelSimons wants to merge 15 commits intodotnet:mainfrom
MichaelSimons:xunit-v3

Conversation

@MichaelSimons
Copy link
Member

@MichaelSimons MichaelSimons commented Feb 10, 2026

Related to #52914.

Switch all ~55 test projects from xUnit v2 (2.9.3) to xUnit v3 (3.1.0) using the arcade SDK's built-in XUnitV3.targets support.

Key changes:

  • Enable TestRunnerName=XUnitV3 in test/Directory.Build.props
  • Switch from Microsoft.DotNet.XUnitExtensions to XUnitV3Extensions
  • Upgrade Xunit.Combinatorial 1.3.2 -> 2.0.24 (v3-compatible)
  • Switch Verify.Xunit -> Verify.XunitV3
  • Rewrite test entry point (Program.cs) as ModuleInitializer
  • Update ITestOutputHelper implementations (new Write/Output members)
  • Fix IMessageSink namespace (Xunit.Abstractions -> Xunit.Sdk)
  • Fix DiagnosticMessage namespace (Xunit.Sdk -> Xunit.v3)
  • Add CallerFilePath/CallerLineNumber ctors for custom attributes (xUnit3003)
  • Rewrite dotnet-format custom discoverers using IBeforeAfterTestAttribute
  • Exclude transitive v2 assemblies that conflict with v3 types
  • Add TestContext alias to resolve Xunit.TestContext ambiguity
  • Use xunit.v3.assert for non-test projects (SDDLTests)

Switch all ~55 test projects from xUnit v2 (2.9.3) to xUnit v3 (3.1.0)
using the arcade SDK's built-in XUnitV3.targets support.

Key changes:
- Enable TestRunnerName=XUnitV3 in test/Directory.Build.props
- Switch from Microsoft.DotNet.XUnitExtensions to XUnitV3Extensions
- Upgrade Xunit.Combinatorial 1.3.2 -> 2.0.24 (v3-compatible)
- Switch Verify.Xunit -> Verify.XunitV3
- Rewrite test entry point (Program.cs) as ModuleInitializer
- Update ITestOutputHelper implementations (new Write/Output members)
- Fix IMessageSink namespace (Xunit.Abstractions -> Xunit.Sdk)
- Fix DiagnosticMessage namespace (Xunit.Sdk -> Xunit.v3)
- Add CallerFilePath/CallerLineNumber ctors for custom attributes (xUnit3003)
- Rewrite dotnet-format custom discoverers using IBeforeAfterTestAttribute
- Exclude transitive v2 assemblies that conflict with v3 types
- Add TestContext alias to resolve Xunit.TestContext ambiguity
- Use xunit.v3.assert for non-test projects (SDDLTests)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MichaelSimons and others added 13 commits March 3, 2026 17:00
…eues

xUnit v3 runs tests out-of-process via a native AppHost, so when
cross-compiling (e.g. ARM64 macOS build targeting x64 Helix queues)
the publish step must set RuntimeIdentifier to produce the correct
AppHost architecture.

In CI, Arcade's centralized NuGet restore (via NuGet.targets) does not
include RuntimeIdentifier, so the assets file lacks the RID target.
An explicit Restore with RuntimeIdentifiers (plural) is added before
PublishWithOutput to inject the RID target without clobbering multi-TFM
transitive dependencies (e.g. BrowserRefresh which targets net6.0).

ErrorOnDuplicatePublishOutputFiles=false suppresses NETSDK1152 from Exe
project-references (e.g. dotnet.csproj) whose outputs appear in both
the plain-TFM and RID-qualified directories.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…etPackageAdd

WarmUpNuGetCache: check exit code, add timeout handling, and verify
ILLink analyzer DLLs exist after warm-up so failures are surfaced
instead of silently causing CSC-only assertion failures.

GivenDotnetPackageAdd file-based tests: use RestoreAdditionalProjectSources
instead of RestoreSources to add local package paths without replacing
NuGet.config feeds. With xUnit v3 hash-based ordering, the NuGet cache
may not be pre-populated when these tests run.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… dependency

Both tests created a tool named MyFileBasedTool v1.0.0 with different source.
With xUnit v3 hash-based ordering, Pack_CustomPath runs first and installs the
tool; Pack then reuses the cached install instead of its own nupkg, missing the
#if !DEBUG output. Rename to PackTool and PackCustomPathTool respectively.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
WarmUpNuGetCache was using raw Process.Start which did not set the
NUGET_PACKAGES environment variable that DotnetCommand sets via
AddTestEnvironmentVariables. This caused packages to be restored to
the default NuGet cache (~/.nuget/packages) while the actual tests
resolved to the artifacts cache, so the ILLink analyzer DLLs were
not found and GetBuildLevel() fell back to BuildLevel.All.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants