Migrate MSBuild tests from xUnit v2 to xUnit v3#13215
Conversation
Co-authored-by: rainersigwald <3347530+rainersigwald@users.noreply.github.com>
…ttribute implementations - Remove Microsoft.DotNet.XUnitExtensions PackageReference from src/Directory.Build.targets - Remove Microsoft.DotNet.XUnitExtensions PackageVersion from Directory.Packages.props - Change Xunit.NetCore.Extensions to reference xunit.v3.extensibility.core instead of xunit.v3.core - Update UseInvariantCultureAttribute to use xUnit v3 BeforeAfterTestAttribute API - Create v3-compatible attribute implementations in src/Xunit.NetCore.Extensions/Attributes/: - WindowsOnlyFact/Theory, UnixOnlyFact/Theory, LinuxOnlyFact - WindowsFullFrameworkOnlyFact/Theory, DotNetOnlyFact/Theory - ConditionalFact (uses SkipUnless), ActiveIssue (ITraitAttribute) - SkipOnPlatform (BeforeAfterTestAttribute with DynamicSkipToken) - TestPlatforms and TargetFrameworkMonikers enums - DiscovererHelpers utility class Co-authored-by: rainersigwald <3347530+rainersigwald@users.noreply.github.com>
…it1051, DefaultOutput Co-authored-by: rainersigwald <3347530+rainersigwald@users.noreply.github.com>
|
|
||
| namespace Xunit | ||
| { | ||
| public class WindowsFullFrameworkOnlyFactAttribute : FactAttribute |
There was a problem hiding this comment.
@copilot do not duplicate the attributes that can be found in the Xunit.NetCore.Extensions package that was updated in dotnet/arcade#15671. Reference that package explicitly and remove any of the redundant classes in this project.
In fact, evaluate whether there's anything unique in this repo's fork of Xunit.NetCore.Extensions now that the fixture stuff is built into xunitv3. If not, remove the entire project. If so, minimize what's in this project and make it very clear why it needs to exist.
There was a problem hiding this comment.
Replaced local attribute duplicates with Microsoft.DotNet.XUnitV3Extensions package reference. The Xunit.NetCore.Extensions project now only contains 3 files that aren't in the package:
ConditionalFactAttribute— xUnit v3 wrapper usingSkipUnless(not in the v3 extensions package)UseInvariantCultureAttribute— MSBuild-specificBeforeAfterTestAttributefor invariant cultureCustomXunitAttributesUtilities— MSBuild-specific helpers (IsBuiltAgainstNetFramework,AppendAdditionalMessage)
Commit: 3b028f2
| using Xunit; | ||
| using Xunit.v3; | ||
|
|
||
| #nullable disable |
There was a problem hiding this comment.
This is new code -- do not do this.
| #nullable disable |
There was a problem hiding this comment.
Removed. Restored the original MSBuildTestEnvironmentFixture class in TestAssemblyInfo.cs using v3's built-in [AssemblyFixture]. Commit: 3b028f2
| <!-- xUnit v3 packages used by test library (extensibility.core avoids Exe requirement) --> | ||
| <PackageReference Include="xunit.v3.assert" VersionOverride="$(XUnitV3Version)" /> | ||
| <PackageReference Include="xunit.v3.extensibility.core" VersionOverride="$(XUnitV3Version)" /> |
There was a problem hiding this comment.
Are the VersionOverrides still needed? If so, restore the reasoning in the comment.
There was a problem hiding this comment.
Yes, VersionOverrides are still needed — these non-test library projects (IsTestProject=false) don't get Arcade's implicit xunit package references, so they need explicit VersionOverride to resolve the version. Restored the original comment explaining this. Commit: 3b028f2
…ate attributes and MSBuildTestEnvironmentBeforeAfterAttribute Co-authored-by: rainersigwald <3347530+rainersigwald@users.noreply.github.com>
rainersigwald
left a comment
There was a problem hiding this comment.
##[error]C:\Program Files\Microsoft Visual Studio\18\Insiders\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets(2437,5): error MSB3243: No way to resolve conflict between "Microsoft.Bcl.AsyncInterfaces, Version=9.0.0.11, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" and "Microsoft.Bcl.AsyncInterfaces, Version=9.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51". Choosing "Microsoft.Bcl.AsyncInterfaces, Version=9.0.0.11, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" arbitrarily.
And it looks like several tests are failing in AzDO. Run all the test projects locally.
…ensions from non-test library project Co-authored-by: rainersigwald <3347530+rainersigwald@users.noreply.github.com>
|
The Test results run locally (Linux/net10.0):
|
|
@copilot I pulled this locally and see failed tests: ❯ pushd src/Framework.UnitTets && dotnet test
...
Microsoft.Build.Framework.UnitTests net10.0 succeeded (0.1s) → /home/raines/src/msbuild/artifacts/bin/Microsoft.Build.Framework.UnitTests/Debug/net10.0/Microsoft.Build.Framework.UnitTests.dll
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v3.1.3+b1b99bdeb3 (64-bit .NET 10.0.1)
[xUnit.net 00:00:00.12] Discovering: Microsoft.Build.Framework.UnitTests (app domain = off, method display = ClassAndMethod, method display options = None)
[xUnit.net 00:00:00.29] Discovered: Microsoft.Build.Framework.UnitTests (106 test cases to be run)
[xUnit.net 00:00:00.42] Starting: Microsoft.Build.Framework.UnitTests (parallel test collections = off, stop on fail = off, explicit = off, seed = 1459758606)
[xUnit.net 00:00:00.66] Microsoft.Build.UnitTests.AbsolutePath_Tests.AbsolutePath_CaseInsensitive_OnWindows [SKIP]
[xUnit.net 00:00:00.66] This test requires Windows to run.
[xUnit.net 00:00:00.68] Microsoft.Build.UnitTests.AbsolutePath_Tests.AbsolutePath_WindowsPathValidation_ShouldAcceptOnlyTrueAbsolutePaths [SKIP]
[xUnit.net 00:00:00.68] This test requires Windows to run.
[xUnit.net 00:00:00.68] Microsoft.Build.UnitTests.AbsolutePath_Tests.AbsolutePath_NotRooted_ShouldThrowWithLocalizedMessage [SKIP]
[xUnit.net 00:00:00.68] This test requires Windows to run.
[xUnit.net 00:00:00.83] [Test Assembly Cleanup Failure (/home/raines/src/msbuild/artifacts/bin/Microsoft.Build.Framework.UnitTests/Debug/net10.0/Microsoft.Build.Framework.UnitTests.dll)] Xunit.Sdk.TestPipelineException
[xUnit.net 00:00:00.83] Assembly fixture type 'Microsoft.Build.UnitTests.MSBuildTestEnvironmentFixture' threw in Dispose
[xUnit.net 00:00:00.83] ---- Expected Path.GetTempPath() to be '/tmp/5i32rbs5.ykd/', but it was '/tmp/'
[xUnit.net 00:00:00.83] Stack Trace:
[xUnit.net 00:00:00.83] --- End of stack trace from previous location ---
[xUnit.net 00:00:00.83] ----- Inner Stack Trace -----
[xUnit.net 00:00:00.83] /home/raines/src/msbuild/src/UnitTests.Shared/TestEnvironment.cs(465,0): at Microsoft.Build.UnitTests.StringInvariant.AssertInvariant(ITestOutputHelper output)
[xUnit.net 00:00:00.83] /home/raines/src/msbuild/src/UnitTests.Shared/TestEnvironment.cs(115,0): at Microsoft.Build.UnitTests.TestEnvironment.Cleanup()
[xUnit.net 00:00:00.83] /home/raines/src/msbuild/src/UnitTests.Shared/TestEnvironment.cs(88,0): at Microsoft.Build.UnitTests.TestEnvironment.Dispose()
[xUnit.net 00:00:00.83] /home/raines/src/msbuild/src/Shared/UnitTests/TestAssemblyInfo.cs(175,0): at Microsoft.Build.UnitTests.MSBuildTestEnvironmentFixture.Dispose()
[xUnit.net 00:00:00.83] Finished: Microsoft.Build.Framework.UnitTests
Microsoft.Build.Framework.UnitTests test net10.0 failed with 1 error(s) (1.3s)
/home/raines/src/msbuild/.dotnet/sdk/10.0.101/Microsoft.TestPlatform.targets(48,5): error MSB6006: "dotnet" exited with code 1.
Test summary: total: 106, failed: 0, succeeded: 103, skipped: 3, duration: 1.3s
Build failed with 1 error(s) in 6.8s |
…sembly-scope fixture that can't work with v3's scope model Co-authored-by: rainersigwald <3347530+rainersigwald@users.noreply.github.com>
... The Removed the fixture since it can't serve its original purpose (per-class/method invariant checking) with v3's assembly-only scope. The assembly-level Verified locally — no more cleanup failure: Commit: 526ae29 |
This resolves an assembly conflict bewteen newer xUnitV3 references and our frozen `Microsoft.Bcl.AsyncInterfaces`. There's no need to freeze anything here, because this test helper is used only in our repo and for our tests that reference everything at the expected-at-runtime new/higher version.
Instead of methods.
…otnet/msbuild into copilot/migrate-xunit-v2-to-v3
Context
Migrates the MSBuild test infrastructure from xUnit v2 (2.9.3) to xUnit v3 (3.0.0) using Arcade SDK's
TestRunnerName=XUnitV3support. KeepsUseVSTestRunner=trueso the VSTest runner (dotnet test) is preserved — no filter syntax, dump argument, or MTP package changes needed.Changes Made
Build configuration (
Directory.Build.targets,Directory.Build.props,Directory.Packages.props):TestRunnerName=XUnitV3,UseMicrosoftTestingPlatformRunner=falsexunit.consolepackage,TestProgram.csinclude,GenerateProgramFile=false, v2-specific--DiagflagxUnit1004(skip warning) andxUnit1051(CancellationToken recommendation)Package references:
xunit.core/xunit.assert→xunit.v3.extensibility.core/xunit.v3.assertVerify.Xunit→Verify.XunitV3(removed[UsesVerify]— unnecessary in v3)Microsoft.DotNet.XUnitExtensions(depends on v2, causes type conflicts) withMicrosoft.DotNet.XUnitV3Extensions(v3-compatible, depends onxunit.v3.extensibility.core)Microsoft.DotNet.XUnitV3Extensionsis only referenced in test projects (viaDirectory.Build.targets), not in theXunit.NetCore.Extensionslibrary project, to avoid a transitiveMicrosoft.Bcl.AsyncInterfacesversion conflict with the repo's frozen maintenance package versionsNamespace migration (119 files):
using Xunit.Abstractions;→using Xunit;(ITestOutputHelpermoved)IXunitSerializable/IXunitSerializationInfo→Xunit.SdknamespaceITestOutputHelpergainedOutputproperty andWrite()methodsAssemblyFixture rewrite:
XunitTestFrameworkWithAssemblyFixture, etc.)[AssemblyFixture]— no customTestFrameworkregistration neededMSBuildTestAssemblyFixtureregistered via v3's built-in[AssemblyFixture]MSBuildTestEnvironmentFixture— this fixture was designed for per-class and per-method scopes in the v2 custom runner, but xUnit v3's[AssemblyFixture]only supports assembly scope. At assembly scope, it caused cleanup failures because theTestEnvironmentrecorded the custom temp path set byMSBuildTestAssemblyFixture, then failed on dispose when the temp path had already been restored. The assembly-levelMSBuildTestAssemblyFixturestill provides all core test environment setup.Minimized
Xunit.NetCore.Extensionsproject — only retains MSBuild-specific code not available inMicrosoft.DotNet.XUnitV3Extensions:ConditionalFactAttribute: v3 wrapper usingSkipUnless(not in the v3 extensions package)UseInvariantCultureAttribute: updatedBeforeAfterTestAttributesignature for v3CustomXunitAttributesUtilities: MSBuild-specific helpers (IsBuiltAgainstNetFramework,AppendAdditionalMessage)Config:
xunit.runner.json: removed v2-onlyshadowCopy,appDomainTesting
Notes
Microsoft.DotNet.XUnitExtensionsis fundamentally incompatible with v3 (its attributes extend v2'sFactAttribute). The v3 replacementMicrosoft.DotNet.XUnitV3Extensions(same Arcade SDK version) provides all standard attributes (WindowsOnlyFact,ActiveIssue,SkipOnPlatform, etc.) and depends onxunit.v3.extensibility.core.VersionOverrides inUnitTests.Shared.csprojandXunit.NetCore.Extensions.csprojare still needed because these non-test library projects (IsTestProject=false) don't get Arcade's implicit xunit package references.Microsoft.DotNet.XUnitV3Extensionsmust not be referenced fromXunit.NetCore.Extensions.csproj(a non-test library) because its transitive dependency onMicrosoft.Bcl.AsyncInterfaces 9.0.0-rc.2conflicts with the repo's frozen version9.0.11in .NET Framework builds. Test projects already get it fromDirectory.Build.targets.[AssemblyFixture]only supports assembly scope, unlike v2's custom runner which supported Class and Method scopes. Per-class/per-method invariant checking viaMSBuildTestEnvironmentFixtureis no longer available.✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.