Convert Mono.Linker.Tests from MSTest to xUnit#126613
Draft
Conversation
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/60c12141-7156-45f9-900a-6298193c1612 Co-authored-by: sbomer <787361+sbomer@users.noreply.github.com>
…lity checks Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/60c12141-7156-45f9-900a-6298193c1612 Co-authored-by: sbomer <787361+sbomer@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Convert illink tests from MSTest to xUnit
Convert Mono.Linker.Tests from MSTest to xUnit
Apr 7, 2026
jkoritzinsky
reviewed
Apr 7, 2026
…degenAnnotationTests Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/bec1ccc1-bf1f-4de2-bf2d-ab95d9017603 Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
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.
Description
Converts
Mono.Linker.Tests— the last remaining MSTest project in illink — to xUnit, aligning it with the rest ofdotnet/runtime's test infrastructure.Changes
Project setup
<TestRunnerName>MSTest</TestRunnerName>from csproj; xUnit is now the default via ArcadeMicrosoft.DotNet.XUnitExtensionsPackageReference (not auto-imported forsrc/tools/illink/)Test data / dynamic data
TestDatabase: return types changed fromIEnumerable<TestDataRow<TestCase>>→IEnumerable<object[]>;MSTestCasesBySuiteName→TestCasesBySuiteNameMemberAssertionsCollector.GetMemberAssertionsData: returnsIEnumerable<object[]>instead ofIEnumerable<TestDataRow<T>>TestCase.ToString()added to emitDisplayNamefor readable xUnit test names[DynamicData(..., new object[] { typeof(T) })]with parameterized data source → parameterless[MemberData]method per test classTest attributes
[TestClass]removed;[TestMethod]→[Fact];[DataRow]→[InlineData][DynamicData]→[MemberData]; suite tests use[ConditionalTheory](not plain[Theory]) to support dynamic skipping[TestInitialize]→ constructor;[DoNotParallelize]removed (MSTest-only concept)AssemblyInfo.csparallel configuration removedDynamic skipping
MSTest's
Assert.Inconclusivedoesn't translate directly to xUnit's skip mechanism. Most runtime skipping usesConditionalTheory+SkipTestExceptionfromMicrosoft.DotNet.XUnitExtensions. ForCodegenAnnotationTests, declarative[SkipOnTargetFramework]attributes are used instead:The
[SkipOnTargetFramework]attribute adds aCategory=Failingtrait viaSkipOnTargetFrameworkDiscoverer, which is automatically filtered out by the CI infrastructure via_withoutCategories=failingineng/testing/tests.targets.Assertions (all files)
Assert.AreEqual(a, b)Assert.Equal(a, b)Assert.IsTrue/IsFalseAssert.True/FalseAssert.IsNull/IsNotNullAssert.Null/NotNullAssert.IsEmptyAssert.EmptyAssert.Inconclusivethrow new SkipTestExceptionCollectionAssert.AreEquivalentAssert.Equal(a.OrderBy(...), b.OrderBy(...))UnitTestAssertExceptionXunitExceptionTesting
Build:
dotnet build src/tools/illink/test/Mono.Linker.Tests/Mono.Linker.Tests.csproj -c ReleaseRun:
dotnet test src/tools/illink/test/Mono.Linker.Tests/Mono.Linker.Tests.csproj -c ReleaseOriginal prompt
Chronological Review: 1. User requested converting illink tests from MSTest to xUnit 2. Prior work (summarized): Explored repo, found only Mono.Linker.Tests uses MSTest, ran baseline build, delegated bulk conversion to sub-agent (22 files), committed as 9425ffe083f 3. Prior work: Discovered 31 test failures due to dynamic skip mechanism, fixed with ConditionalTheory + SkipTestException (3 files) 4. Prior work: Started code review skill, gathered diff context 5. Current session: Completed code review and amended commitRecent Commands Analysis:
Progress: Everything is DONE. The task is complete.
1. Conversation Overview: - Primary Objectives: "Update the illink tests from MSTest to xunit." - Session Context: User requested converting `Mono.Linker.Tests` (the last MSTest test project in illink) to xUnit. Work progressed through exploration → bulk conversion → fixing dynamic skip failures → code review → final commit. - User Intent Evolution: Single clear request, no changes in direction.-
- xUnit v2 runner (2.9.x) with xUnit v3 assertions (
- Arcade SDK:
- Microsoft.DotNet.XUnitExtensions: Provides
- SDK version: 11.0.100-preview.3.26170.106
-
- All 22 files committed in single commit
- Key files:
- 16 other files with attribute/using/assertion conversions
-
- 31 test failures from dynamic skip:
- Assert.NotNull message loss: xUnit's
- Assert.AreEqual with message: One instance converted to
-
- ✅ Baseline build succeeded
- ✅ All 22 files converted from MSTest to xUnit
- ✅ Dynamic skip mechanism fixed (ConditionalTheory + SkipTestException)
- ✅ Build passes (0 errors, 0 warnings)
- ✅ Tests pass: 0 Failed, 1125 Passed, 31 Skipped
- ✅ Code review completed (LGTM, one 💡 suggestion)
- ✅ All changes committed in single amended commit
- ✅
-
- Task is COMPLETE.
-
- Last Agent Commands:
- Wrote code review output (LGTM with findings)
- `ta...
Technical Foundation:
Microsoft.DotNet.XUnitAssert3.2.2-beta) — the dotnet/runtime standard setupTests.targetsdefaultsTestRunnerName=XUnit; removing<TestRunnerName>MSTest</TestRunnerName>switches to xUnit packages automaticallyConditionalTheory/ConditionalFactandSkipTestExceptionfor dynamic test skipping. NOT auto-imported forsrc/tools/illink/(only forsrc/libraries/andsrc/tests/), so needed explicit PackageReference.Codebase Status:
2a2d31b5610on branchillink-xunitMono.Linker.Tests.csproj— RemovedTestRunnerName=MSTest, addedMicrosoft.DotNet.XUnitExtensionsPackageReferenceTestSuites.cs— 47[ConditionalTheory]methods,[MemberData]instead of[DynamicData],SkipTestExceptionfor dynamic skipsTestRunner.cs—IgnoreTestthrowsSkipTestException, catchesXunitExceptioninstead ofUnitTestAssertExceptionTestDatabase.cs—object[]instead ofTestDataRow<TestCase>, renamedMSTestCasesBySuiteName→TestCasesBySuiteNameTestCase.cs— AddedToString()override returningDisplayNameResultChecker.cs— Dozens of assertion conversions; 3Assert.NotNullcalls lost custom messages; 1Assert.True(a == b, msg)pattern at line 259Problem Resolution:
SkipException.ForSkip()(Xunit.Sdk) produces$XunitDynamicSkip$prefix not caught by xUnit v2 runner. Fixed by usingConditionalTheory+SkipTestExceptionfromMicrosoft.DotNet.XUnitExtensions.Assert.NotNulldoesn't accept messages. Accepted as known tradeoff (3 instances).Assert.True(a == b, msg)to preserve diagnostic output including linker output.Progress Tracking:
2a2d31b5610task_completecalledActive Work State:
task_completewas called with full summary.Recent Operations:
bash:git diff HEAD~1 -- ResultChecker.cs | grep "Assert.AreEqual.*Assert.True"— no resultsbash:git diff HEAD~1 -- ResultChecker.cs | grep -A1 "Assert.AreEqual"— found the 3 AreEqual conversions including the Assert.True patternbash:grep "Assert.True.*==\|Assert.False.*!=" ResultChecker.cs— confirmed only 1 instance at line 259bash:grep "SkipTestException" TestSuites.cs— confirmed 2 usagesbash:git add -A && git diff --cached --stat— staged 3 files (csproj, TestSuites.cs, TestRunner.cs)bash:git commit --amend— amended commit to2a2d31b5610with 22 files, 369 insertions, 396 deletionsbash:git log --oneline -2— verified commit onillink-xunitbranchCreated from Copilot CLI via the copilot delegate command.