Skip to content

Convert Mono.Linker.Tests from MSTest to xUnit#126613

Draft
Copilot wants to merge 4 commits intomainfrom
copilot/convert-illink-tests-to-xunit
Draft

Convert Mono.Linker.Tests from MSTest to xUnit#126613
Copilot wants to merge 4 commits intomainfrom
copilot/convert-illink-tests-to-xunit

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 7, 2026

Description

Converts Mono.Linker.Tests — the last remaining MSTest project in illink — to xUnit, aligning it with the rest of dotnet/runtime's test infrastructure.

Changes

Project setup

  • Remove <TestRunnerName>MSTest</TestRunnerName> from csproj; xUnit is now the default via Arcade
  • Add explicit Microsoft.DotNet.XUnitExtensions PackageReference (not auto-imported for src/tools/illink/)

Test data / dynamic data

  • TestDatabase: return types changed from IEnumerable<TestDataRow<TestCase>>IEnumerable<object[]>; MSTestCasesBySuiteNameTestCasesBySuiteName
  • MemberAssertionsCollector.GetMemberAssertionsData: returns IEnumerable<object[]> instead of IEnumerable<TestDataRow<T>>
  • TestCase.ToString() added to emit DisplayName for readable xUnit test names
  • [DynamicData(..., new object[] { typeof(T) })] with parameterized data source → parameterless [MemberData] method per test class

Test 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.cs parallel configuration removed

Dynamic skipping
MSTest's Assert.Inconclusive doesn't translate directly to xUnit's skip mechanism. Most runtime skipping uses ConditionalTheory + SkipTestException from Microsoft.DotNet.XUnitExtensions. For CodegenAnnotationTests, declarative [SkipOnTargetFramework] attributes are used instead:

// Before (MSTest)
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
    Assert.Inconclusive("These tests are not valid when trimming .NET Framework");
#if NET
Assert.Inconclusive("These tests are not valid when trimming .NET Core");
#endif

// After (xUnit)
[SkipOnTargetFramework(TargetFrameworkMonikers.Netcoreapp, "These tests are not valid when trimming .NET Core")]
[SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "These tests are not valid when trimming .NET Framework")]

The [SkipOnTargetFramework] attribute adds a Category=Failing trait via SkipOnTargetFrameworkDiscoverer, which is automatically filtered out by the CI infrastructure via _withoutCategories=failing in eng/testing/tests.targets.

Assertions (all files)

MSTest xUnit
Assert.AreEqual(a, b) Assert.Equal(a, b)
Assert.IsTrue/IsFalse Assert.True/False
Assert.IsNull/IsNotNull Assert.Null/NotNull
Assert.IsEmpty Assert.Empty
Assert.Inconclusive throw new SkipTestException
CollectionAssert.AreEquivalent Assert.Equal(a.OrderBy(...), b.OrderBy(...))
UnitTestAssertException XunitException

Testing

Build: dotnet build src/tools/illink/test/Mono.Linker.Tests/Mono.Linker.Tests.csproj -c Release

Run: dotnet test src/tools/illink/test/Mono.Linker.Tests/Mono.Linker.Tests.csproj -c Release

Original 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 commit

Recent Commands Analysis:

  • Checked AreEqual→Assert.True conversions in ResultChecker.cs diff
  • Verified SkipTestException and ConditionalTheory usage in TestSuites.cs
  • Found only 1 instance of Assert.True(a == b, msg) pattern at line 259
  • Wrote code review (LGTM with one 💡 suggestion about Assert.NotNull message loss)
  • Staged 3 uncommitted files and amended commit
  • Final commit: 2a2d31b5610
  • Called task_complete

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.
  1. Technical Foundation:

    • xUnit v2 runner (2.9.x) with xUnit v3 assertions (Microsoft.DotNet.XUnitAssert 3.2.2-beta) — the dotnet/runtime standard setup
    • Arcade SDK: Tests.targets defaults TestRunnerName=XUnit; removing <TestRunnerName>MSTest</TestRunnerName> switches to xUnit packages automatically
    • Microsoft.DotNet.XUnitExtensions: Provides ConditionalTheory/ConditionalFact and SkipTestException for dynamic test skipping. NOT auto-imported for src/tools/illink/ (only for src/libraries/ and src/tests/), so needed explicit PackageReference.
    • SDK version: 11.0.100-preview.3.26170.106
  2. Codebase Status:

    • All 22 files committed in single commit 2a2d31b5610 on branch illink-xunit
    • Key files:
      • Mono.Linker.Tests.csproj — Removed TestRunnerName=MSTest, added Microsoft.DotNet.XUnitExtensions PackageReference
      • TestSuites.cs — 47 [ConditionalTheory] methods, [MemberData] instead of [DynamicData], SkipTestException for dynamic skips
      • TestRunner.csIgnoreTest throws SkipTestException, catches XunitException instead of UnitTestAssertException
      • TestDatabase.csobject[] instead of TestDataRow<TestCase>, renamed MSTestCasesBySuiteNameTestCasesBySuiteName
      • TestCase.cs — Added ToString() override returning DisplayName
      • ResultChecker.cs — Dozens of assertion conversions; 3 Assert.NotNull calls lost custom messages; 1 Assert.True(a == b, msg) pattern at line 259
      • 16 other files with attribute/using/assertion conversions
  3. Problem Resolution:

    • 31 test failures from dynamic skip: SkipException.ForSkip() (Xunit.Sdk) produces $XunitDynamicSkip$ prefix not caught by xUnit v2 runner. Fixed by using ConditionalTheory + SkipTestException from Microsoft.DotNet.XUnitExtensions.
    • Assert.NotNull message loss: xUnit's Assert.NotNull doesn't accept messages. Accepted as known tradeoff (3 instances).
    • Assert.AreEqual with message: One instance converted to Assert.True(a == b, msg) to preserve diagnostic output including linker output.
  4. Progress Tracking:

    • ✅ 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 2a2d31b5610
    • task_complete called
  5. Active Work State:

    • Task is COMPLETE. task_complete was called with full summary.
  6. Recent Operations:

    • Last Agent Commands:
      1. bash: git diff HEAD~1 -- ResultChecker.cs | grep "Assert.AreEqual.*Assert.True" — no results
      2. bash: git diff HEAD~1 -- ResultChecker.cs | grep -A1 "Assert.AreEqual" — found the 3 AreEqual conversions including the Assert.True pattern
      3. bash: grep "Assert.True.*==\|Assert.False.*!=" ResultChecker.cs — confirmed only 1 instance at line 259
      4. bash: grep "SkipTestException" TestSuites.cs — confirmed 2 usages
      5. Wrote code review output (LGTM with findings)
      6. bash: git add -A && git diff --cached --stat — staged 3 files (csproj, TestSuites.cs, TestRunner.cs)
      7. bash: git commit --amend — amended commit to 2a2d31b5610 with 22 files, 369 insertions, 396 deletions
      8. bash: git log --oneline -2 — verified commit on illink-xunit branch
      9. `ta...

Created from Copilot CLI via the copilot delegate command.

Copilot AI requested review from Copilot and removed request for Copilot April 7, 2026 19:46
@dotnet-policy-service dotnet-policy-service bot added the linkable-framework Issues associated with delivering a linker friendly framework label Apr 7, 2026
Copilot AI requested review from Copilot and removed request for Copilot April 7, 2026 19:50
Copilot AI changed the title [WIP] Convert illink tests from MSTest to xUnit Convert Mono.Linker.Tests from MSTest to xUnit Apr 7, 2026
Copilot AI requested a review from sbomer April 7, 2026 19:53
…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>
Copilot AI requested review from Copilot and removed request for Copilot April 7, 2026 20:30
Copilot AI requested a review from jkoritzinsky April 7, 2026 20:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-Infrastructure linkable-framework Issues associated with delivering a linker friendly framework

Projects

Status: No status
Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants