From 578ae61df0f1077c698e93929b4fee27a7d6584f Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Wed, 16 Sep 2026 04:38:24 +0000 Subject: [PATCH 1/4] Add an xUnit v3 opt-in for library tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21b4fbf8-d548-4f4d-a033-aa8e36080965 --- eng/testing/xunit/xunit.console.targets | 30 ++++++++++++------- eng/testing/xunit/xunit.props | 11 +++++-- eng/testing/xunit/xunit.targets | 11 +++++++ .../TestUtilities/RandomTestCaseOrderer.cs | 10 +++++++ .../RandomTestCollectionOrderer.cs | 10 +++++++ .../tests/TestUtilities/TestEventListener.cs | 4 +++ .../tests/TestUtilities/TestUtilities.csproj | 10 +++++-- src/libraries/Directory.Build.props | 11 ++++++- 8 files changed, 79 insertions(+), 18 deletions(-) diff --git a/eng/testing/xunit/xunit.console.targets b/eng/testing/xunit/xunit.console.targets index e3b2fbfa916bb6..c348bd8eb4ff7a 100644 --- a/eng/testing/xunit/xunit.console.targets +++ b/eng/testing/xunit/xunit.console.targets @@ -23,16 +23,23 @@ <_depsFileArgument Condition="'$(GenerateDependencyFile)' == 'true'">--depsfile $(AssemblyName).deps.json - "$(RunScriptHost)" exec --runtimeconfig $(AssemblyName).runtimeconfig.json $(_depsFileArgument) $(XunitConsolePath) - $(XunitConsolePath) + "$(RunScriptHost)" exec --runtimeconfig $(AssemblyName).runtimeconfig.json $(_depsFileArgument) $(XunitConsolePath) + $(XunitConsolePath) + "$(RunScriptHost)" exec --runtimeconfig $(AssemblyName).runtimeconfig.json $(_depsFileArgument) $(TargetFileName) + ./$(AssemblyName) + $(AssemblyName).exe - $(RunScriptCommand) $(TargetFileName) + $(RunScriptCommand) $(TargetFileName) $(RunScriptCommand) -xml $(TestResultsName) - $(RunScriptCommand) -nologo - $(RunScriptCommand) -nocolor + $(RunScriptCommand) -nologo + $(RunScriptCommand) -noLogo + $(RunScriptCommand) -nocolor + $(RunScriptCommand) -noColor $(RunScriptCommand) -noappdomain - $(RunScriptCommand) -maxthreads 1 - $(RunScriptCommand) -verbose + $(RunScriptCommand) -maxthreads 1 + $(RunScriptCommand) -maxThreads 1 + $(RunScriptCommand) -verbose + $(RunScriptCommand) -reporter verbose @@ -42,7 +49,8 @@ $(RunScriptCommand)$(_withCategories.Replace(';', ' -trait category=')) - $(RunScriptCommand)$(_withoutCategories.Replace(';', ' -notrait category=')) + $(RunScriptCommand)$(_withoutCategories.Replace(';', ' -notrait category=')) + $(RunScriptCommand)$(_withoutCategories.Replace(';', ' -trait- category=')) $(RunScriptCommand) $(XUnitOptions) @@ -60,11 +68,11 @@ + Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and '$(UseXUnitV3)' != 'true'" /> + Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework' and '$(UseXUnitV3)' != 'true'" /> @@ -83,7 +91,7 @@ - + Exe $(NoWarn);xUnit1051 @@ -10,13 +11,17 @@ - + + - + + + - + + false + $(DefineConstants);XUNIT_V3 @@ -106,8 +107,10 @@ - - + + + + @@ -122,7 +125,8 @@ - + + diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index b85797ae211c21..e7a7e0d7584db7 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -11,6 +11,14 @@ + + $(ArtifactsBinDir)TestUtilities.XUnitV3/ + $(ArtifactsObjDir)TestUtilities.XUnitV3/ + $(BaseOutputPath)$(Configuration)/ + $(BaseIntermediateOutputPath)$(Configuration)/ + $(BaseIntermediateOutputPath) + + true @@ -80,7 +88,8 @@ - + From 91dbe76409c8c3606f5b31984df2d53660310d0b Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Wed, 16 Sep 2026 04:38:33 +0000 Subject: [PATCH 2/4] Convert System.Collections.Tests to xUnit v3 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21b4fbf8-d548-4f4d-a033-aa8e36080965 --- src/libraries/System.Collections/Directory.Build.props | 8 ++++++++ .../tests/Generic/Comparers/EqualityComparer.Tests.cs | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Collections/Directory.Build.props b/src/libraries/System.Collections/Directory.Build.props index 63f02a0f817ef2..96768d6366dacd 100644 --- a/src/libraries/System.Collections/Directory.Build.props +++ b/src/libraries/System.Collections/Directory.Build.props @@ -1,6 +1,14 @@  + true Microsoft \ No newline at end of file diff --git a/src/libraries/System.Collections/tests/Generic/Comparers/EqualityComparer.Tests.cs b/src/libraries/System.Collections/tests/Generic/Comparers/EqualityComparer.Tests.cs index b45874cd3e3f31..43f935d69ad2bf 100644 --- a/src/libraries/System.Collections/tests/Generic/Comparers/EqualityComparer.Tests.cs +++ b/src/libraries/System.Collections/tests/Generic/Comparers/EqualityComparer.Tests.cs @@ -16,8 +16,8 @@ public IEnumerable Items { get { - return this.Select(array => array[0]) - .Concat(this.Select(array => array[1])) + return this.Select(row => row.Data.Item1) + .Concat(this.Select(row => row.Data.Item2)) .Cast(); } } From 68367ca1caec1a743d7f253481b1da113fc42577 Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Thu, 17 Sep 2026 05:08:28 +0000 Subject: [PATCH 3/4] Split xUnit v2 and v3 test infrastructure Keep the console runner targets and TestUtilities project identities separate while sharing the common TestUtilities source definition. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21b4fbf8-d548-4f4d-a033-aa8e36080965 --- eng/testing/xunit/xunit.console.targets | 30 ++--- eng/testing/xunit/xunit.console.v3.targets | 50 +++++++ eng/testing/xunit/xunit.targets | 3 +- .../TestUtilities/TestUtilities.Shared.props | 122 +++++++++++++++++ .../TestUtilities.XUnitV3.csproj | 19 +++ .../tests/TestUtilities/TestUtilities.csproj | 127 +----------------- src/libraries/Directory.Build.props | 12 +- 7 files changed, 211 insertions(+), 152 deletions(-) create mode 100644 eng/testing/xunit/xunit.console.v3.targets create mode 100644 src/libraries/Common/tests/TestUtilities/TestUtilities.Shared.props create mode 100644 src/libraries/Common/tests/TestUtilities/TestUtilities.XUnitV3.csproj diff --git a/eng/testing/xunit/xunit.console.targets b/eng/testing/xunit/xunit.console.targets index c348bd8eb4ff7a..e3b2fbfa916bb6 100644 --- a/eng/testing/xunit/xunit.console.targets +++ b/eng/testing/xunit/xunit.console.targets @@ -23,23 +23,16 @@ <_depsFileArgument Condition="'$(GenerateDependencyFile)' == 'true'">--depsfile $(AssemblyName).deps.json - "$(RunScriptHost)" exec --runtimeconfig $(AssemblyName).runtimeconfig.json $(_depsFileArgument) $(XunitConsolePath) - $(XunitConsolePath) - "$(RunScriptHost)" exec --runtimeconfig $(AssemblyName).runtimeconfig.json $(_depsFileArgument) $(TargetFileName) - ./$(AssemblyName) - $(AssemblyName).exe + "$(RunScriptHost)" exec --runtimeconfig $(AssemblyName).runtimeconfig.json $(_depsFileArgument) $(XunitConsolePath) + $(XunitConsolePath) - $(RunScriptCommand) $(TargetFileName) + $(RunScriptCommand) $(TargetFileName) $(RunScriptCommand) -xml $(TestResultsName) - $(RunScriptCommand) -nologo - $(RunScriptCommand) -noLogo - $(RunScriptCommand) -nocolor - $(RunScriptCommand) -noColor + $(RunScriptCommand) -nologo + $(RunScriptCommand) -nocolor $(RunScriptCommand) -noappdomain - $(RunScriptCommand) -maxthreads 1 - $(RunScriptCommand) -maxThreads 1 - $(RunScriptCommand) -verbose - $(RunScriptCommand) -reporter verbose + $(RunScriptCommand) -maxthreads 1 + $(RunScriptCommand) -verbose @@ -49,8 +42,7 @@ $(RunScriptCommand)$(_withCategories.Replace(';', ' -trait category=')) - $(RunScriptCommand)$(_withoutCategories.Replace(';', ' -notrait category=')) - $(RunScriptCommand)$(_withoutCategories.Replace(';', ' -trait- category=')) + $(RunScriptCommand)$(_withoutCategories.Replace(';', ' -notrait category=')) $(RunScriptCommand) $(XUnitOptions) @@ -68,11 +60,11 @@ + Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'" /> + Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'" /> @@ -91,7 +83,7 @@ - + true + + + + + + + + + <_depsFileArgument Condition="'$(GenerateDependencyFile)' == 'true'">--depsfile $(AssemblyName).deps.json + "$(RunScriptHost)" exec --runtimeconfig $(AssemblyName).runtimeconfig.json $(_depsFileArgument) $(TargetFileName) + ./$(AssemblyName) + $(AssemblyName).exe + + $(RunScriptCommand) -xml $(TestResultsName) + $(RunScriptCommand) -noLogo + $(RunScriptCommand) -noColor + $(RunScriptCommand) -noappdomain + $(RunScriptCommand) -maxThreads 1 + $(RunScriptCommand) -reporter verbose + + + + + $(RunScriptCommand) -method $(XUnitMethodName) + $(RunScriptCommand) -class $(XUnitClassName) + + + $(RunScriptCommand)$(_withCategories.Replace(';', ' -trait category=')) + $(RunScriptCommand)$(_withoutCategories.Replace(';', ' -trait- category=')) + + + $(RunScriptCommand) $(XUnitOptions) + + + + $(_withoutCategories.Replace(';', '%0dcategory=')) + + + + + $(RunScriptCommand) -xml $(TestResultsName) + + + diff --git a/eng/testing/xunit/xunit.targets b/eng/testing/xunit/xunit.targets index 797462f09546ee..59212954ca468b 100644 --- a/eng/testing/xunit/xunit.targets +++ b/eng/testing/xunit/xunit.targets @@ -30,5 +30,6 @@ Condition="'$(OutputType)' != 'Exe'" /> - + + diff --git a/src/libraries/Common/tests/TestUtilities/TestUtilities.Shared.props b/src/libraries/Common/tests/TestUtilities/TestUtilities.Shared.props new file mode 100644 index 00000000000000..90eb7f490f9898 --- /dev/null +++ b/src/libraries/Common/tests/TestUtilities/TestUtilities.Shared.props @@ -0,0 +1,122 @@ + + + $(NetCoreAppMinimum);$(NetFrameworkCurrent) + true + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/Common/tests/TestUtilities/TestUtilities.XUnitV3.csproj b/src/libraries/Common/tests/TestUtilities/TestUtilities.XUnitV3.csproj new file mode 100644 index 00000000000000..8edd3b0e1ca5ba --- /dev/null +++ b/src/libraries/Common/tests/TestUtilities/TestUtilities.XUnitV3.csproj @@ -0,0 +1,19 @@ + + + TestUtilities + TestUtilities + $(DefineConstants);XUNIT_V3 + + + + + + + + + + + + + + diff --git a/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj b/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj index e68cd455d933ee..a3290f42b7a808 100644 --- a/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj +++ b/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj @@ -1,132 +1,13 @@ - - $(NetCoreAppMinimum);$(NetFrameworkCurrent) - true - - false - $(DefineConstants);XUNIT_V3 - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - + diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index e7a7e0d7584db7..5c87ba21c3da44 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -11,14 +11,6 @@ - - $(ArtifactsBinDir)TestUtilities.XUnitV3/ - $(ArtifactsObjDir)TestUtilities.XUnitV3/ - $(BaseOutputPath)$(Configuration)/ - $(BaseIntermediateOutputPath)$(Configuration)/ - $(BaseIntermediateOutputPath) - - true @@ -89,7 +81,9 @@ + Condition="'$(UseXUnitV3)' != 'true'" /> + From b49e9e219e667ed931ce7dcac6bafc295f1021e7 Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Thu, 17 Sep 2026 05:42:37 +0000 Subject: [PATCH 4/4] Centralize the xUnit v3 test opt-in Use xunit.v3.assert throughout xUnit v3 builds and keep the project allowlist in shared library test infrastructure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21b4fbf8-d548-4f4d-a033-aa8e36080965 --- eng/testing/xunit/xunit.props | 5 ++--- .../TestUtilities/TestUtilities.Shared.props | 5 ----- .../TestUtilities/TestUtilities.XUnitV3.csproj | 5 +---- .../tests/TestUtilities/TestUtilities.csproj | 5 +++++ src/libraries/Directory.Build.props | 16 ++++++++++++++++ .../System.Collections/Directory.Build.props | 8 -------- 6 files changed, 24 insertions(+), 20 deletions(-) diff --git a/eng/testing/xunit/xunit.props b/eng/testing/xunit/xunit.props index bf28dbdc622887..92b2a2d9c18b67 100644 --- a/eng/testing/xunit/xunit.props +++ b/eng/testing/xunit/xunit.props @@ -16,9 +16,8 @@ - - - + + diff --git a/src/libraries/Common/tests/TestUtilities/TestUtilities.Shared.props b/src/libraries/Common/tests/TestUtilities/TestUtilities.Shared.props index 90eb7f490f9898..c7cbb36e392ebb 100644 --- a/src/libraries/Common/tests/TestUtilities/TestUtilities.Shared.props +++ b/src/libraries/Common/tests/TestUtilities/TestUtilities.Shared.props @@ -105,11 +105,6 @@ Link="Common\Interop\Android\System.Security.Cryptography.Native.Android\Interop.Ssl.ProtocolSupport.cs" /> - - - - - diff --git a/src/libraries/Common/tests/TestUtilities/TestUtilities.XUnitV3.csproj b/src/libraries/Common/tests/TestUtilities/TestUtilities.XUnitV3.csproj index 8edd3b0e1ca5ba..37d3829cb44f96 100644 --- a/src/libraries/Common/tests/TestUtilities/TestUtilities.XUnitV3.csproj +++ b/src/libraries/Common/tests/TestUtilities/TestUtilities.XUnitV3.csproj @@ -9,11 +9,8 @@ - - - - + diff --git a/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj b/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj index a3290f42b7a808..fe2b4dfde0ecd3 100644 --- a/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj +++ b/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj @@ -6,6 +6,11 @@ + + + + + diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index 5c87ba21c3da44..351957fc8ed1fd 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -79,6 +79,22 @@ $([MSBuild]::NormalizeDirectory('$(CommonPathRoot)', 'tests')) + + + + System.Collections.Tests; + + true + + diff --git a/src/libraries/System.Collections/Directory.Build.props b/src/libraries/System.Collections/Directory.Build.props index 96768d6366dacd..63f02a0f817ef2 100644 --- a/src/libraries/System.Collections/Directory.Build.props +++ b/src/libraries/System.Collections/Directory.Build.props @@ -1,14 +1,6 @@  - true Microsoft \ No newline at end of file