Skip to content

Migrate Microsoft.DotNet.HotReload.Watch.Aspire.Tests to MSTest.Sdk on MTP (pathfinder)#54722

Open
Evangelink wants to merge 8 commits into
dotnet:mainfrom
Evangelink:evangelink/mstest-mtp-aspire-tests-pathfinder
Open

Migrate Microsoft.DotNet.HotReload.Watch.Aspire.Tests to MSTest.Sdk on MTP (pathfinder)#54722
Evangelink wants to merge 8 commits into
dotnet:mainfrom
Evangelink:evangelink/mstest-mtp-aspire-tests-pathfinder

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Pathfinder PR for migrating the test suite to MSTest on Microsoft.Testing.Platform (MTP) via MSTest.Sdk.

Microsoft.DotNet.HotReload.Watch.Aspire.Tests was chosen because it has no dependency on the shared Microsoft.NET.TestFramework (which is xUnit-coupled and referenced by ~57 of 78 test projects), so it can migrate in isolation without unblocking dependents first.

Changes

  • global.json: add MSTest.Sdk 4.3.0-preview.26307.5 to msbuild-sdks (version already pinned in eng/Version.Details.props).
  • test/Directory.Build.targets: gate the xUnit-v3 defaults (TestRunnerName=XUnitV3, Using Include="Xunit", packages) behind '$(UseMSTestSdk)' != 'true'. Establishes the per-project opt-out pattern future migrations will reuse.
  • test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests
    • csproj now uses Sdk="MSTest.Sdk", sets UseMSTestSdk=true, references AwesomeAssertions and only the Watch.Aspire project. MTP is on by default via MSTest.Sdk (EnableMSTestRunner + TestingPlatformDotnetTestSupport).
    • All 4 unit-test files converted from xUnit to MSTest attributes/asserts ([Fact]/[Theory][TestMethod]/[DataRow], Assert.* equivalents, Assert.IsInstanceOfType<T> (returns T in 4.x), Assert.HasCount, Assert.IsEmpty).
    • Local AssertEx.SequenceEqual<T> helper replaces the xUnit-coupled one from HotReload.Test.Utilities.
  • Moved the 2 integration tests (AspireLauncherTests + PipeUtilities) to test/dotnet-watch.Tests/Aspire/ so the Aspire.Tests project stays a pure MSTest unit-test project. They stay on xUnit because they depend on WatchSdkTest, WatchableApp, [PlatformSpecificFact], ITestOutputHelper and TestAssets from Microsoft.NET.TestFramework. AspireLauncherTests renamed to AspireLauncherIntegrationTests.
  • src/Dotnet.Watch/Watch.Aspire/Properties/AssemblyInfo.cs: grant InternalsVisibleTo to dotnet-watch.Tests (needed by PipeUtilities, which uses internal WatchStatusEvent).
  • test/dotnet-watch.Tests/dotnet-watch.Tests.csproj: add ProjectReference to Watch.Aspire (ExcludeAssets=Runtime) so the moved integration tests compile.

Verification

  • Microsoft.DotNet.HotReload.Watch.Aspire.Tests builds with MSTest.Sdk.
  • All 58 unit tests pass on MTP (705 ms).
  • test/dotnet-watch.Tests builds successfully with the moved files.

Next steps (follow-up PRs)

Small mergeable PRs to progressively migrate the rest:

  1. Migrate other test projects that don't depend on Microsoft.NET.TestFramework (a handful).
  2. Dual-target Microsoft.NET.TestFramework's assertion/attribute surface across xUnit & MSTest to unblock the ~57 dependents.
  3. Bulk-migrate dependents 1–few at a time.
  4. Final flip: drop xUnit defaults from test/Directory.Build.targets.

Relates to #52914.

Copilot AI review requested due to automatic review settings June 11, 2026 19:22
@Evangelink Evangelink requested review from a team and tmat as code owners June 11, 2026 19:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR is a pathfinder migration that moves Microsoft.DotNet.HotReload.Watch.Aspire.Tests off the repo’s xUnit defaults and onto MSTest.Sdk (Microsoft.Testing.Platform), while keeping xUnit-based integration tests in dotnet-watch.Tests where they still depend on Microsoft.NET.TestFramework.

Changes:

  • Add MSTest.Sdk to global.json and introduce a UseMSTestSdk=true opt-out switch to bypass xUnit-v3 defaults from test/Directory.Build.targets.
  • Convert the Aspire unit test project to Sdk="MSTest.Sdk" and update test sources from xUnit attributes/asserts to MSTest equivalents, including a project-local AssertEx.
  • Move Aspire integration tests/utilities into test/dotnet-watch.Tests/Aspire/ and add InternalsVisibleTo/ProjectReference changes so they can access Watch.Aspire internals.
Show a summary per file
File Description
global.json Registers MSTest.Sdk as an MSBuild SDK for the repo.
test/Directory.Build.targets Gates xUnit-v3 test defaults behind UseMSTestSdk != true to enable per-project MSTest adoption.
test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/Microsoft.DotNet.HotReload.Watch.Aspire.Tests.csproj Switches the unit test project to MSTest.Sdk and removes reliance on xUnit-coupled shared utilities.
test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AssertEx.cs Adds a local assertion helper to replace the xUnit-coupled shared AssertEx.
test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireServerLauncherCliTests.cs Migrates tests from xUnit to MSTest.
test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireResourceLauncherCliTests.cs Migrates tests from xUnit to MSTest and keeps assertion style via Should() APIs.
test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireHostLauncherTests.cs Migrates tests from xUnit to MSTest.
test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireHostLauncherCliTests.cs Migrates tests from xUnit to MSTest.
src/Dotnet.Watch/Watch.Aspire/Properties/AssemblyInfo.cs Adds InternalsVisibleTo for dotnet-watch.Tests to support moved integration utilities.
test/dotnet-watch.Tests/dotnet-watch.Tests.csproj Adds a Watch.Aspire project reference needed by the moved integration tests.
test/dotnet-watch.Tests/Aspire/PipeUtilities.cs Introduces helper for reading WatchStatusEvent from a named pipe in integration tests.
test/dotnet-watch.Tests/Aspire/AspireLauncherIntegrationTests.cs Renames the integration test class after the move to dotnet-watch.Tests.

Copilot's findings

  • Files reviewed: 11/12 changed files
  • Comments generated: 1

Comment on lines +14 to +16
<PackageReference Include="AwesomeAssertions" />
<Using Include="FluentAssertions" />
<Using Include="Microsoft.VisualStudio.TestTools.UnitTesting" />

@tmat tmat left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we migrating away from XUnit?

@Evangelink Evangelink marked this pull request as draft June 11, 2026 19:53
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 11, 2026
Follow-up to the pathfinder migration. containerize.UnitTests only uses xUnit
Fact/Theory/InlineData/Assert APIs - it does not use any types from
Microsoft.NET.TestFramework. So the project can drop its TestFramework
ProjectReference and switch to MSTest.Sdk in one self-contained PR.

Changes:
* test/containerize.UnitTests/containerize.UnitTests.csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true (opts the project out of the
    xUnit defaults in test/Directory.Build.targets - gate introduced in PR dotnet#54722).
  - Drop the ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* test/containerize.UnitTests/ParserTests.cs: xUnit -> MSTest mechanical
  conversion: [Fact]/[Theory] -> [TestMethod], [InlineData] -> [DataRow],
  add [TestClass], Assert.NotNull/Equal/Empty/Single ->
  IsNotNull/AreEqual/IsEmpty/HasCount(1, ...).

Verification: 9/9 tests pass on MTP in ~400 ms.

Stacks on top of PR dotnet#54722 (pathfinder). Merge after that one.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 11, 2026
Same pattern as containerize.UnitTests (dotnet#54723). This project's single test
file only uses xUnit Fact/Assert.Equal - no Microsoft.NET.TestFramework
types - so the TestFramework ProjectReference can be dropped and the
project switched to MSTest.Sdk in one self-contained change.

Changes:
* test/Microsoft.DotNet.ApiCompat.Tests/Microsoft.DotNet.ApiCompat.Tests.csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true.
  - Drop ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* test/Microsoft.DotNet.ApiCompat.Tests/RegexStringTransformerTests.cs:
  [Fact] -> [TestMethod], add [TestClass], Assert.Equal -> Assert.AreEqual.

Verification: 5/5 tests pass on MTP in ~250 ms.

Stacks on top of dotnet#54723 which stacks on dotnet#54722.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 11, 2026
Follow-up to the pathfinder migration. containerize.UnitTests only uses xUnit
Fact/Theory/InlineData/Assert APIs - it does not use any types from
Microsoft.NET.TestFramework. So the project can drop its TestFramework
ProjectReference and switch to MSTest.Sdk in one self-contained PR.

Changes:
* test/containerize.UnitTests/containerize.UnitTests.csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true (opts the project out of the
    xUnit defaults in test/Directory.Build.targets - gate introduced in PR dotnet#54722).
  - Drop the ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* test/containerize.UnitTests/ParserTests.cs: xUnit -> MSTest mechanical
  conversion: [Fact]/[Theory] -> [TestMethod], [InlineData] -> [DataRow],
  add [TestClass], Assert.NotNull/Equal/Empty/Single ->
  IsNotNull/AreEqual/IsEmpty/HasCount(1, ...).

Verification: 9/9 tests pass on MTP in ~400 ms.

Stacks on top of PR dotnet#54722 (pathfinder). Merge after that one.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 11, 2026
Same pattern as containerize.UnitTests (dotnet#54723). This project's single test
file only uses xUnit Fact/Assert.Equal - no Microsoft.NET.TestFramework
types - so the TestFramework ProjectReference can be dropped and the
project switched to MSTest.Sdk in one self-contained change.

Changes:
* test/Microsoft.DotNet.ApiCompat.Tests/Microsoft.DotNet.ApiCompat.Tests.csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true.
  - Drop ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* test/Microsoft.DotNet.ApiCompat.Tests/RegexStringTransformerTests.cs:
  [Fact] -> [TestMethod], add [TestClass], Assert.Equal -> Assert.AreEqual.

Verification: 5/5 tests pass on MTP in ~250 ms.

Stacks on top of dotnet#54723 which stacks on dotnet#54722.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 11, 2026
… on MTP

Same pattern as previous migrations. None of the 6 test files used any
Microsoft.NET.TestFramework types - only xUnit primitives - so the
TestFramework ProjectReference can be dropped and the project switched to
MSTest.Sdk in one self-contained change.

Changes:
* test/Microsoft.AspNetCore.Watch.BrowserRefresh.Tests/csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true.
  - Drop ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* 6 test files: xUnit -> MSTest mechanical conversion plus targeted fixes:
  - [Fact]/[Theory] -> [TestMethod], [InlineData] -> [DataRow], add [TestClass].
  - Assert.True/False/Null/NotNull/Empty/NotEmpty/Equal/NotEqual ->
    IsTrue/IsFalse/IsNull/IsNotNull/IsEmpty/IsNotEmpty/AreEqual/AreNotEqual.
  - Assert.Single(x) -> Assert.HasCount(1, x).
  - String Assert.Contains(needle, haystack) -> StringAssert.Contains(haystack, needle)
    (xUnit and MSTest argument orders are reversed).
  - One Assert.DoesNotContain(needle, str) -> Assert.IsFalse(str.Contains(needle)).
  - Assert.Collection in BrowserScriptMiddlewareTest expanded to inline
    Assert.HasCount + indexed AreEqual checks.
  - Assert.ThrowsAsync<T> -> Assert.ThrowsExactlyAsync<T>.
  - Assert.AreEqual on byte[]/int[] -> Assert.AreSequenceEqual (MSTEST0065:
    MSTest does not do element-wise equality on collections; the analyzer
    catches a real semantic difference vs xUnit).
  - StringValues (Microsoft.Extensions.Primitives) ambiguity with
    Assert.AreEqual<T> resolved by calling .ToString() at 5 call sites.
  - xUnit v3 TestContext.Current.CancellationToken -> CancellationToken.None
    (MSTest's TestContext.Current is experimental; tests do not actually
    require test-cancellation propagation).

Verification: 110/110 tests pass on MTP in ~480 ms.

Stacks on dotnet#54724 which stacks on dotnet#54723 which stacks on dotnet#54722.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 11, 2026
…tain for strings

The migrate-xunit-to-mstest skill (.github/skills/migrate-xunit-to-mstest,
PR dotnet#54727) notes that MSTest 3.8+ added Assert.Contains(needle, str) /
Assert.DoesNotContain(needle, str) overloads for strings -- with the
natural (needle, haystack) argument order matching xUnit's
Assert.Contains. With the 4.3.0-preview MSTest.Sdk bump in dotnet#54722, these
are now available throughout the migration.

Replaced:
- StringAssert.Contains(haystack, needle)  -> Assert.Contains(needle, haystack)
- Assert.IsFalse(haystack.Contains(needle)) -> Assert.DoesNotContain(needle, haystack)

Touched files:
- BrowserRefreshMiddlewareTest.cs
- BrowserScriptMiddlewareTest.cs
- ResponseStreamWrapperCompressionTest.cs

Note: Assert.IsFalse(dict.ContainsKey(key)) call sites are unchanged
(no Assert.DoesNotContainKey API exists).

Verified: 110/110 tests still pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
Member Author

Re-validated this PR against the new migrate-xunit-to-mstest skill landed in #54727 and bumped MSTest.Sdk to 4.3.0-preview.26311.10 (latest internal preview) via the pathfinder.

Changes applied in the latest push on this branch:
IsInstanceOfType -> IsExactInstanceOfType at 39 call sites (exact-type semantics matching xUnit Assert.IsType); Assert.HasCount(1, x) -> Assert.ContainsSingle(x); MSTest.Sdk bumped to 4.3.0-preview.26311.10 for the new APIs.

Other gotchas reviewed (no changes needed here):

  • Assert.AreEqual argument order — verified (expected, actual) throughout, matching the xUnit Assert.Equal(expected, actual) original.
  • CollectionAssert argument order — verified.
  • Assert.ThrowsExactly<T> vs Assert.Throws<T> semantics — verified (xUnit Throws<T> is exact; MSTest's same-named API is inclusive, so the migration uses ThrowsExactly<T>).
  • IsInstanceOfType<T> vs IsExactInstanceOfType<T> — see dotnet/skills#755 for the cheatsheet update we filed upstream.

Tests still pass locally on the bumped MSTest.Sdk.

@Evangelink

Copy link
Copy Markdown
Member Author

Why the file moves + new InternalsVisibleTo("dotnet-watch.Tests")

Heads-up for reviewers about the only non-mechanical changes in this otherwise pure xUnit → MSTest mechanical migration:

Two file renames (cross-project moves)

From To
test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireLauncherTests.cs test/dotnet-watch.Tests/Aspire/AspireLauncherIntegrationTests.cs
test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/Utilities/PipeUtilities.cs test/dotnet-watch.Tests/Aspire/PipeUtilities.cs

(Confirmed as git renames — similarity 98 % and 100 %.)

Why: AspireLauncherTests is an integration test, not a unit test. It depends on the repo's xUnit-coupled test infrastructure:

  • Extends WatchSdkTest (xUnit SdkTest subclass)
  • Constructor ITestOutputHelper logger (xUnit-specific)
  • [PlatformSpecificFact] (TestFramework xUnit attribute)
  • WatchableApp, TestAssets.CopyTestAsset(...), SdkTestContext.Current.ToolsetUnderTest.SdkFolderUnderTest (TestFramework helpers; xUnit-coupled today)

That dependency surface cannot move to MSTest as part of a "pathfinder" PR — decoupling Microsoft.NET.TestFramework from xUnit is its own multi-PR workstream. So instead of trying to drag the integration test through, it moved to dotnet-watch.Tests/Aspire/ where the xUnit infrastructure already lives. PipeUtilities followed because the integration test is its only consumer.

The renamed file is appended with Integration (AspireLauncherIntegrationTests) to make the unit/integration split explicit going forward. After the move:

  • Microsoft.DotNet.HotReload.Watch.Aspire.Tests (this PR, now MSTest) holds pure unit tests for the three sealed AspireLauncher subclasses.
  • dotnet-watch.Tests/Aspire/ (still xUnit) holds the end-to-end integration tests that actually exec the host/server/resource binaries.

New [InternalsVisibleTo("dotnet-watch.Tests", PublicKey=...)]

Added to src/Dotnet.Watch/Watch.Aspire/Properties/AssemblyInfo.cs alongside the existing IVT to the unit-test project.

Why: the moved integration test references typeof(AspireLauncher).Assembly.Location to locate the launcher executable. AspireLauncher is internal abstract (source). The xUnit unit-test project (Microsoft.DotNet.HotReload.Watch.Aspire.Tests) already had an IVT for the same reason; the new entry simply mirrors it to dotnet-watch.Tests, which is the new home for that test. The IVT uses the same Microsoft.AspNetCore strong-name public key already used throughout the assembly's IVT list.

No production code or production behavior is affected — only test-assembly visibility.

Happy to split these two changes out of the migration PR if reviewers prefer them in a separate prep PR; left them together because they're the precondition for the migration (you can't migrate AspireLauncherTests without first relocating it).

Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 11, 2026
Follow-up to the pathfinder migration. containerize.UnitTests only uses xUnit
Fact/Theory/InlineData/Assert APIs - it does not use any types from
Microsoft.NET.TestFramework. So the project can drop its TestFramework
ProjectReference and switch to MSTest.Sdk in one self-contained PR.

Changes:
* test/containerize.UnitTests/containerize.UnitTests.csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true (opts the project out of the
    xUnit defaults in test/Directory.Build.targets - gate introduced in PR dotnet#54722).
  - Drop the ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* test/containerize.UnitTests/ParserTests.cs: xUnit -> MSTest mechanical
  conversion: [Fact]/[Theory] -> [TestMethod], [InlineData] -> [DataRow],
  add [TestClass], Assert.NotNull/Equal/Empty/Single ->
  IsNotNull/AreEqual/IsEmpty/HasCount(1, ...).

Verification: 9/9 tests pass on MTP in ~400 ms.

Stacks on top of PR dotnet#54722 (pathfinder). Merge after that one.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 11, 2026
Same pattern as containerize.UnitTests (dotnet#54723). This project's single test
file only uses xUnit Fact/Assert.Equal - no Microsoft.NET.TestFramework
types - so the TestFramework ProjectReference can be dropped and the
project switched to MSTest.Sdk in one self-contained change.

Changes:
* test/Microsoft.DotNet.ApiCompat.Tests/Microsoft.DotNet.ApiCompat.Tests.csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true.
  - Drop ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* test/Microsoft.DotNet.ApiCompat.Tests/RegexStringTransformerTests.cs:
  [Fact] -> [TestMethod], add [TestClass], Assert.Equal -> Assert.AreEqual.

Verification: 5/5 tests pass on MTP in ~250 ms.

Stacks on top of dotnet#54723 which stacks on dotnet#54722.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 11, 2026
… on MTP

Same pattern as previous migrations. None of the 6 test files used any
Microsoft.NET.TestFramework types - only xUnit primitives - so the
TestFramework ProjectReference can be dropped and the project switched to
MSTest.Sdk in one self-contained change.

Changes:
* test/Microsoft.AspNetCore.Watch.BrowserRefresh.Tests/csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true.
  - Drop ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* 6 test files: xUnit -> MSTest mechanical conversion plus targeted fixes:
  - [Fact]/[Theory] -> [TestMethod], [InlineData] -> [DataRow], add [TestClass].
  - Assert.True/False/Null/NotNull/Empty/NotEmpty/Equal/NotEqual ->
    IsTrue/IsFalse/IsNull/IsNotNull/IsEmpty/IsNotEmpty/AreEqual/AreNotEqual.
  - Assert.Single(x) -> Assert.HasCount(1, x).
  - String Assert.Contains(needle, haystack) -> StringAssert.Contains(haystack, needle)
    (xUnit and MSTest argument orders are reversed).
  - One Assert.DoesNotContain(needle, str) -> Assert.IsFalse(str.Contains(needle)).
  - Assert.Collection in BrowserScriptMiddlewareTest expanded to inline
    Assert.HasCount + indexed AreEqual checks.
  - Assert.ThrowsAsync<T> -> Assert.ThrowsExactlyAsync<T>.
  - Assert.AreEqual on byte[]/int[] -> Assert.AreSequenceEqual (MSTEST0065:
    MSTest does not do element-wise equality on collections; the analyzer
    catches a real semantic difference vs xUnit).
  - StringValues (Microsoft.Extensions.Primitives) ambiguity with
    Assert.AreEqual<T> resolved by calling .ToString() at 5 call sites.
  - xUnit v3 TestContext.Current.CancellationToken -> CancellationToken.None
    (MSTest's TestContext.Current is experimental; tests do not actually
    require test-cancellation propagation).

Verification: 110/110 tests pass on MTP in ~480 ms.

Stacks on dotnet#54724 which stacks on dotnet#54723 which stacks on dotnet#54722.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 11, 2026
…tain for strings

The migrate-xunit-to-mstest skill (.github/skills/migrate-xunit-to-mstest,
PR dotnet#54727) notes that MSTest 3.8+ added Assert.Contains(needle, str) /
Assert.DoesNotContain(needle, str) overloads for strings -- with the
natural (needle, haystack) argument order matching xUnit's
Assert.Contains. With the 4.3.0-preview MSTest.Sdk bump in dotnet#54722, these
are now available throughout the migration.

Replaced:
- StringAssert.Contains(haystack, needle)  -> Assert.Contains(needle, haystack)
- Assert.IsFalse(haystack.Contains(needle)) -> Assert.DoesNotContain(needle, haystack)

Touched files:
- BrowserRefreshMiddlewareTest.cs
- BrowserScriptMiddlewareTest.cs
- ResponseStreamWrapperCompressionTest.cs

Note: Assert.IsFalse(dict.ContainsKey(key)) call sites are unchanged
(no Assert.DoesNotContainKey API exists).

Verified: 110/110 tests still pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 11, 2026
Follow-up to the pathfinder migration. containerize.UnitTests only uses xUnit
Fact/Theory/InlineData/Assert APIs - it does not use any types from
Microsoft.NET.TestFramework. So the project can drop its TestFramework
ProjectReference and switch to MSTest.Sdk in one self-contained PR.

Changes:
* test/containerize.UnitTests/containerize.UnitTests.csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true (opts the project out of the
    xUnit defaults in test/Directory.Build.targets - gate introduced in PR dotnet#54722).
  - Drop the ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* test/containerize.UnitTests/ParserTests.cs: xUnit -> MSTest mechanical
  conversion: [Fact]/[Theory] -> [TestMethod], [InlineData] -> [DataRow],
  add [TestClass], Assert.NotNull/Equal/Empty/Single ->
  IsNotNull/AreEqual/IsEmpty/HasCount(1, ...).

Verification: 9/9 tests pass on MTP in ~400 ms.

Stacks on top of PR dotnet#54722 (pathfinder). Merge after that one.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 11, 2026
Same pattern as containerize.UnitTests (dotnet#54723). This project's single test
file only uses xUnit Fact/Assert.Equal - no Microsoft.NET.TestFramework
types - so the TestFramework ProjectReference can be dropped and the
project switched to MSTest.Sdk in one self-contained change.

Changes:
* test/Microsoft.DotNet.ApiCompat.Tests/Microsoft.DotNet.ApiCompat.Tests.csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true.
  - Drop ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* test/Microsoft.DotNet.ApiCompat.Tests/RegexStringTransformerTests.cs:
  [Fact] -> [TestMethod], add [TestClass], Assert.Equal -> Assert.AreEqual.

Verification: 5/5 tests pass on MTP in ~250 ms.

Stacks on top of dotnet#54723 which stacks on dotnet#54722.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 11, 2026
… on MTP

Same pattern as previous migrations. None of the 6 test files used any
Microsoft.NET.TestFramework types - only xUnit primitives - so the
TestFramework ProjectReference can be dropped and the project switched to
MSTest.Sdk in one self-contained change.

Changes:
* test/Microsoft.AspNetCore.Watch.BrowserRefresh.Tests/csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true.
  - Drop ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* 6 test files: xUnit -> MSTest mechanical conversion plus targeted fixes:
  - [Fact]/[Theory] -> [TestMethod], [InlineData] -> [DataRow], add [TestClass].
  - Assert.True/False/Null/NotNull/Empty/NotEmpty/Equal/NotEqual ->
    IsTrue/IsFalse/IsNull/IsNotNull/IsEmpty/IsNotEmpty/AreEqual/AreNotEqual.
  - Assert.Single(x) -> Assert.HasCount(1, x).
  - String Assert.Contains(needle, haystack) -> StringAssert.Contains(haystack, needle)
    (xUnit and MSTest argument orders are reversed).
  - One Assert.DoesNotContain(needle, str) -> Assert.IsFalse(str.Contains(needle)).
  - Assert.Collection in BrowserScriptMiddlewareTest expanded to inline
    Assert.HasCount + indexed AreEqual checks.
  - Assert.ThrowsAsync<T> -> Assert.ThrowsExactlyAsync<T>.
  - Assert.AreEqual on byte[]/int[] -> Assert.AreSequenceEqual (MSTEST0065:
    MSTest does not do element-wise equality on collections; the analyzer
    catches a real semantic difference vs xUnit).
  - StringValues (Microsoft.Extensions.Primitives) ambiguity with
    Assert.AreEqual<T> resolved by calling .ToString() at 5 call sites.
  - xUnit v3 TestContext.Current.CancellationToken -> CancellationToken.None
    (MSTest's TestContext.Current is experimental; tests do not actually
    require test-cancellation propagation).

Verification: 110/110 tests pass on MTP in ~480 ms.

Stacks on dotnet#54724 which stacks on dotnet#54723 which stacks on dotnet#54722.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 11, 2026
…tain for strings

The migrate-xunit-to-mstest skill (.github/skills/migrate-xunit-to-mstest,
PR dotnet#54727) notes that MSTest 3.8+ added Assert.Contains(needle, str) /
Assert.DoesNotContain(needle, str) overloads for strings -- with the
natural (needle, haystack) argument order matching xUnit's
Assert.Contains. With the 4.3.0-preview MSTest.Sdk bump in dotnet#54722, these
are now available throughout the migration.

Replaced:
- StringAssert.Contains(haystack, needle)  -> Assert.Contains(needle, haystack)
- Assert.IsFalse(haystack.Contains(needle)) -> Assert.DoesNotContain(needle, haystack)

Touched files:
- BrowserRefreshMiddlewareTest.cs
- BrowserScriptMiddlewareTest.cs
- ResponseStreamWrapperCompressionTest.cs

Note: Assert.IsFalse(dict.ContainsKey(key)) call sites are unchanged
(no Assert.DoesNotContainKey API exists).

Verified: 110/110 tests still pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink and others added 7 commits June 12, 2026 18:03
…n MTP

This is a pathfinder PR for migrating the test suite to MSTest on
Microsoft.Testing.Platform (MTP). Microsoft.DotNet.HotReload.Watch.Aspire.Tests
was chosen because it has no dependency on the shared Microsoft.NET.TestFramework
(which is xUnit-coupled and referenced by ~57 of 78 test projects), so it can
migrate in isolation without unblocking dependents first.

Changes:

* global.json: add MSTest.Sdk 4.3.0-preview.26307.5 to msbuild-sdks.
* test/Directory.Build.targets: gate the xUnit defaults
  (TestRunnerName=XUnitV3, Using Include=Xunit, etc.) behind
  $(UseMSTestSdk) != true, so MSTest.Sdk projects opt out cleanly.
* test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests:
  - csproj now uses Sdk="MSTest.Sdk", sets UseMSTestSdk=true, references
    AwesomeAssertions and only the Watch.Aspire project. MTP is on by default
    via MSTest.Sdk (EnableMSTestRunner + TestingPlatformDotnetTestSupport).
  - All 4 unit-test files converted from xUnit to MSTest attributes/asserts
    ([Fact]/[Theory] -> [TestMethod]/[DataRow], Assert.* equivalents,
    Assert.IsInstanceOfType<T>, Assert.HasCount, Assert.IsEmpty).
  - Local AssertEx.SequenceEqual<T> helper replaces the xUnit-coupled one
    from HotReload.Test.Utilities.
* Move the 2 integration tests (AspireLauncherTests + PipeUtilities) to
  test/dotnet-watch.Tests/Aspire/ so the Aspire.Tests project stays a pure
  MSTest unit-test project. They keep xUnit because they depend on
  WatchSdkTest, WatchableApp, [PlatformSpecificFact], ITestOutputHelper and
  TestAssets from Microsoft.NET.TestFramework. AspireLauncherTests was
  renamed to AspireLauncherIntegrationTests to reflect its new role.
* src/Dotnet.Watch/Watch.Aspire/Properties/AssemblyInfo.cs: grant
  InternalsVisibleTo to dotnet-watch.Tests (needed by PipeUtilities, which
  uses internal WatchStatusEvent).
* test/dotnet-watch.Tests/dotnet-watch.Tests.csproj: add ProjectReference to
  Watch.Aspire (ExcludeAssets=Runtime) so the moved integration tests
  compile.

Verification:
* Microsoft.DotNet.HotReload.Watch.Aspire.Tests builds with MSTest.Sdk and
  all 58 unit tests pass under MTP (705 ms).
* test/dotnet-watch.Tests builds successfully with the moved files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Bumps MSTest.Sdk to the latest internal preview to pick up the newest
  4.3 assertion APIs (Assert.ContainsSingle, Assert.Contains for strings
  with the more natural (needle, haystack) signature, etc.).
- Applies the assertion mapping flagged by the migrate-xunit-to-mstest
  skill in this repo (.github/skills/migrate-xunit-to-mstest, PR dotnet#54727):
    Assert.HasCount(1, x) -> Assert.ContainsSingle(x)
  (one occurrence in AspireResourceLauncherCliTests.cs)

Verified: 58/58 tests still pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…parity

Per reviewer feedback: MSTest 4.1.0+ exposes Assert.IsExactInstanceOfType<T>(value)
which returns T and enforces exact-type semantics -- the proper equivalent
of xUnit's Assert.IsType<T>(x). Assert.IsInstanceOfType<T> is the equivalent
of xUnit's Assert.IsAssignableFrom<T> (assignable, not exact), which would
be a silent semantic regression for the IsType<T> originals.

All 39 occurrences across AspireHostLauncherCliTests.cs,
AspireResourceLauncherCliTests.cs, AspireServerLauncherCliTests.cs, and
AspireLauncherIntegrationTests.cs were originally Assert.IsType<T> in
xUnit (verified against main), so all 39 are flipped to
Assert.IsExactInstanceOfType<T>.

Note: the migrate-xunit-to-mstest skill cheatsheet at
.github/skills/migrate-xunit-to-mstest/references/mapping-cheatsheet.md
recommends `Assert.IsInstanceOfType<T>` plus an extra typeof-check for
exact-type semantics; that guidance predates IsExactInstanceOfType being
available. Follow-up upstream (dotnet/skills) suggested.

Verified: 58/58 Aspire tests still pass; dotnet-watch.Tests builds clean.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
MSTest.Sdk already adds this as an implicit global using.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
MSTest 4.3+ provides Assert.AreSequenceEqual for element-wise IEnumerable<T> compare with a nice diff message, so the project-local AssertEx helper is no longer needed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…est/Directory.Build.targets

Per @Evangelink: keep per-csproj boilerplate minimal. FluentAssertions is now a
global using for any test project (gated on IsTestProject OR UsingMSTestSdk),
and AwesomeAssertions is added as a PackageReference for MSTest.Sdk projects.
xUnit projects continue to pick it up transitively via Microsoft.NET.TestFramework.

The Microsoft.NET.TestFramework.* and Xunit usings remain gated on the xUnit
branch (UsingMSTestSdk != true) because MSTest projects in this repo do not
reference Microsoft.NET.TestFramework; making those usings global would fail
with CS0246.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The recent `Helix dispatcher: gate --report-trx on TrxReport extension
being loaded` commit accidentally removed the ProjectReference to
Microsoft.DotNet.HotReload.Watch.Aspire from dotnet-watch.Tests.csproj
(introduced in the `Migrate Microsoft.DotNet.HotReload.Watch.Aspire.Tests
to MSTest.Sdk on MTP` commit to allow the moved AspireLauncherIntegrationTests
and PipeUtilities to compile).

Without that reference, the build fails with:

    error CS0246: The type or namespace name 'WatchStatusEvent' could not be
    found (are you missing a using directive or an assembly reference?)
    [test/dotnet-watch.Tests/Aspire/PipeUtilities.cs]

Re-add the ProjectReference.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink Evangelink force-pushed the evangelink/mstest-mtp-aspire-tests-pathfinder branch from 0c546a3 to ead0658 Compare June 12, 2026 16:04
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 12, 2026
Follow-up to the pathfinder migration. containerize.UnitTests only uses xUnit
Fact/Theory/InlineData/Assert APIs - it does not use any types from
Microsoft.NET.TestFramework. So the project can drop its TestFramework
ProjectReference and switch to MSTest.Sdk in one self-contained PR.

Changes:
* test/containerize.UnitTests/containerize.UnitTests.csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true (opts the project out of the
    xUnit defaults in test/Directory.Build.targets - gate introduced in PR dotnet#54722).
  - Drop the ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* test/containerize.UnitTests/ParserTests.cs: xUnit -> MSTest mechanical
  conversion: [Fact]/[Theory] -> [TestMethod], [InlineData] -> [DataRow],
  add [TestClass], Assert.NotNull/Equal/Empty/Single ->
  IsNotNull/AreEqual/IsEmpty/HasCount(1, ...).

Verification: 9/9 tests pass on MTP in ~400 ms.

Stacks on top of PR dotnet#54722 (pathfinder). Merge after that one.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 12, 2026
Follow-up to the pathfinder migration. containerize.UnitTests only uses xUnit
Fact/Theory/InlineData/Assert APIs - it does not use any types from
Microsoft.NET.TestFramework. So the project can drop its TestFramework
ProjectReference and switch to MSTest.Sdk in one self-contained PR.

Changes:
* test/containerize.UnitTests/containerize.UnitTests.csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true (opts the project out of the
    xUnit defaults in test/Directory.Build.targets - gate introduced in PR dotnet#54722).
  - Drop the ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* test/containerize.UnitTests/ParserTests.cs: xUnit -> MSTest mechanical
  conversion: [Fact]/[Theory] -> [TestMethod], [InlineData] -> [DataRow],
  add [TestClass], Assert.NotNull/Equal/Empty/Single ->
  IsNotNull/AreEqual/IsEmpty/HasCount(1, ...).

Verification: 9/9 tests pass on MTP in ~400 ms.

Stacks on top of PR dotnet#54722 (pathfinder). Merge after that one.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 12, 2026
Same pattern as containerize.UnitTests (dotnet#54723). This project's single test
file only uses xUnit Fact/Assert.Equal - no Microsoft.NET.TestFramework
types - so the TestFramework ProjectReference can be dropped and the
project switched to MSTest.Sdk in one self-contained change.

Changes:
* test/Microsoft.DotNet.ApiCompat.Tests/Microsoft.DotNet.ApiCompat.Tests.csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true.
  - Drop ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* test/Microsoft.DotNet.ApiCompat.Tests/RegexStringTransformerTests.cs:
  [Fact] -> [TestMethod], add [TestClass], Assert.Equal -> Assert.AreEqual.

Verification: 5/5 tests pass on MTP in ~250 ms.

Stacks on top of dotnet#54723 which stacks on dotnet#54722.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 12, 2026
Follow-up to the pathfinder migration. containerize.UnitTests only uses xUnit
Fact/Theory/InlineData/Assert APIs - it does not use any types from
Microsoft.NET.TestFramework. So the project can drop its TestFramework
ProjectReference and switch to MSTest.Sdk in one self-contained PR.

Changes:
* test/containerize.UnitTests/containerize.UnitTests.csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true (opts the project out of the
    xUnit defaults in test/Directory.Build.targets - gate introduced in PR dotnet#54722).
  - Drop the ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* test/containerize.UnitTests/ParserTests.cs: xUnit -> MSTest mechanical
  conversion: [Fact]/[Theory] -> [TestMethod], [InlineData] -> [DataRow],
  add [TestClass], Assert.NotNull/Equal/Empty/Single ->
  IsNotNull/AreEqual/IsEmpty/HasCount(1, ...).

Verification: 9/9 tests pass on MTP in ~400 ms.

Stacks on top of PR dotnet#54722 (pathfinder). Merge after that one.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 12, 2026
Same pattern as containerize.UnitTests (dotnet#54723). This project's single test
file only uses xUnit Fact/Assert.Equal - no Microsoft.NET.TestFramework
types - so the TestFramework ProjectReference can be dropped and the
project switched to MSTest.Sdk in one self-contained change.

Changes:
* test/Microsoft.DotNet.ApiCompat.Tests/Microsoft.DotNet.ApiCompat.Tests.csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true.
  - Drop ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* test/Microsoft.DotNet.ApiCompat.Tests/RegexStringTransformerTests.cs:
  [Fact] -> [TestMethod], add [TestClass], Assert.Equal -> Assert.AreEqual.

Verification: 5/5 tests pass on MTP in ~250 ms.

Stacks on top of dotnet#54723 which stacks on dotnet#54722.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 12, 2026
… on MTP

Same pattern as previous migrations. None of the 6 test files used any
Microsoft.NET.TestFramework types - only xUnit primitives - so the
TestFramework ProjectReference can be dropped and the project switched to
MSTest.Sdk in one self-contained change.

Changes:
* test/Microsoft.AspNetCore.Watch.BrowserRefresh.Tests/csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true.
  - Drop ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* 6 test files: xUnit -> MSTest mechanical conversion plus targeted fixes:
  - [Fact]/[Theory] -> [TestMethod], [InlineData] -> [DataRow], add [TestClass].
  - Assert.True/False/Null/NotNull/Empty/NotEmpty/Equal/NotEqual ->
    IsTrue/IsFalse/IsNull/IsNotNull/IsEmpty/IsNotEmpty/AreEqual/AreNotEqual.
  - Assert.Single(x) -> Assert.HasCount(1, x).
  - String Assert.Contains(needle, haystack) -> StringAssert.Contains(haystack, needle)
    (xUnit and MSTest argument orders are reversed).
  - One Assert.DoesNotContain(needle, str) -> Assert.IsFalse(str.Contains(needle)).
  - Assert.Collection in BrowserScriptMiddlewareTest expanded to inline
    Assert.HasCount + indexed AreEqual checks.
  - Assert.ThrowsAsync<T> -> Assert.ThrowsExactlyAsync<T>.
  - Assert.AreEqual on byte[]/int[] -> Assert.AreSequenceEqual (MSTEST0065:
    MSTest does not do element-wise equality on collections; the analyzer
    catches a real semantic difference vs xUnit).
  - StringValues (Microsoft.Extensions.Primitives) ambiguity with
    Assert.AreEqual<T> resolved by calling .ToString() at 5 call sites.
  - xUnit v3 TestContext.Current.CancellationToken -> CancellationToken.None
    (MSTest's TestContext.Current is experimental; tests do not actually
    require test-cancellation propagation).

Verification: 110/110 tests pass on MTP in ~480 ms.

Stacks on dotnet#54724 which stacks on dotnet#54723 which stacks on dotnet#54722.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 12, 2026
…tain for strings

The migrate-xunit-to-mstest skill (.github/skills/migrate-xunit-to-mstest,
PR dotnet#54727) notes that MSTest 3.8+ added Assert.Contains(needle, str) /
Assert.DoesNotContain(needle, str) overloads for strings -- with the
natural (needle, haystack) argument order matching xUnit's
Assert.Contains. With the 4.3.0-preview MSTest.Sdk bump in dotnet#54722, these
are now available throughout the migration.

Replaced:
- StringAssert.Contains(haystack, needle)  -> Assert.Contains(needle, haystack)
- Assert.IsFalse(haystack.Contains(needle)) -> Assert.DoesNotContain(needle, haystack)

Touched files:
- BrowserRefreshMiddlewareTest.cs
- BrowserScriptMiddlewareTest.cs
- ResponseStreamWrapperCompressionTest.cs

Note: Assert.IsFalse(dict.ContainsKey(key)) call sites are unchanged
(no Assert.DoesNotContainKey API exists).

Verified: 110/110 tests still pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 12, 2026
Follow-up to the pathfinder migration. containerize.UnitTests only uses xUnit
Fact/Theory/InlineData/Assert APIs - it does not use any types from
Microsoft.NET.TestFramework. So the project can drop its TestFramework
ProjectReference and switch to MSTest.Sdk in one self-contained PR.

Changes:
* test/containerize.UnitTests/containerize.UnitTests.csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true (opts the project out of the
    xUnit defaults in test/Directory.Build.targets - gate introduced in PR dotnet#54722).
  - Drop the ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* test/containerize.UnitTests/ParserTests.cs: xUnit -> MSTest mechanical
  conversion: [Fact]/[Theory] -> [TestMethod], [InlineData] -> [DataRow],
  add [TestClass], Assert.NotNull/Equal/Empty/Single ->
  IsNotNull/AreEqual/IsEmpty/HasCount(1, ...).

Verification: 9/9 tests pass on MTP in ~400 ms.

Stacks on top of PR dotnet#54722 (pathfinder). Merge after that one.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 12, 2026
Same pattern as containerize.UnitTests (dotnet#54723). This project's single test
file only uses xUnit Fact/Assert.Equal - no Microsoft.NET.TestFramework
types - so the TestFramework ProjectReference can be dropped and the
project switched to MSTest.Sdk in one self-contained change.

Changes:
* test/Microsoft.DotNet.ApiCompat.Tests/Microsoft.DotNet.ApiCompat.Tests.csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true.
  - Drop ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* test/Microsoft.DotNet.ApiCompat.Tests/RegexStringTransformerTests.cs:
  [Fact] -> [TestMethod], add [TestClass], Assert.Equal -> Assert.AreEqual.

Verification: 5/5 tests pass on MTP in ~250 ms.

Stacks on top of dotnet#54723 which stacks on dotnet#54722.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 12, 2026
… on MTP

Same pattern as previous migrations. None of the 6 test files used any
Microsoft.NET.TestFramework types - only xUnit primitives - so the
TestFramework ProjectReference can be dropped and the project switched to
MSTest.Sdk in one self-contained change.

Changes:
* test/Microsoft.AspNetCore.Watch.BrowserRefresh.Tests/csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true.
  - Drop ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* 6 test files: xUnit -> MSTest mechanical conversion plus targeted fixes:
  - [Fact]/[Theory] -> [TestMethod], [InlineData] -> [DataRow], add [TestClass].
  - Assert.True/False/Null/NotNull/Empty/NotEmpty/Equal/NotEqual ->
    IsTrue/IsFalse/IsNull/IsNotNull/IsEmpty/IsNotEmpty/AreEqual/AreNotEqual.
  - Assert.Single(x) -> Assert.HasCount(1, x).
  - String Assert.Contains(needle, haystack) -> StringAssert.Contains(haystack, needle)
    (xUnit and MSTest argument orders are reversed).
  - One Assert.DoesNotContain(needle, str) -> Assert.IsFalse(str.Contains(needle)).
  - Assert.Collection in BrowserScriptMiddlewareTest expanded to inline
    Assert.HasCount + indexed AreEqual checks.
  - Assert.ThrowsAsync<T> -> Assert.ThrowsExactlyAsync<T>.
  - Assert.AreEqual on byte[]/int[] -> Assert.AreSequenceEqual (MSTEST0065:
    MSTest does not do element-wise equality on collections; the analyzer
    catches a real semantic difference vs xUnit).
  - StringValues (Microsoft.Extensions.Primitives) ambiguity with
    Assert.AreEqual<T> resolved by calling .ToString() at 5 call sites.
  - xUnit v3 TestContext.Current.CancellationToken -> CancellationToken.None
    (MSTest's TestContext.Current is experimental; tests do not actually
    require test-cancellation propagation).

Verification: 110/110 tests pass on MTP in ~480 ms.

Stacks on dotnet#54724 which stacks on dotnet#54723 which stacks on dotnet#54722.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 12, 2026
…tain for strings

The migrate-xunit-to-mstest skill (.github/skills/migrate-xunit-to-mstest,
PR dotnet#54727) notes that MSTest 3.8+ added Assert.Contains(needle, str) /
Assert.DoesNotContain(needle, str) overloads for strings -- with the
natural (needle, haystack) argument order matching xUnit's
Assert.Contains. With the 4.3.0-preview MSTest.Sdk bump in dotnet#54722, these
are now available throughout the migration.

Replaced:
- StringAssert.Contains(haystack, needle)  -> Assert.Contains(needle, haystack)
- Assert.IsFalse(haystack.Contains(needle)) -> Assert.DoesNotContain(needle, haystack)

Touched files:
- BrowserRefreshMiddlewareTest.cs
- BrowserScriptMiddlewareTest.cs
- ResponseStreamWrapperCompressionTest.cs

Note: Assert.IsFalse(dict.ContainsKey(key)) call sites are unchanged
(no Assert.DoesNotContainKey API exists).

Verified: 110/110 tests still pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Introduces an MSTest-flavored counterpart to the xUnit-based
Microsoft.DotNet.HotReload.Test.Utilities so that test helpers that
need MSTest's TestContext (e.g. TestLogger, TestLoggerFactory) can be
shared across MSTest.Sdk test projects instead of being copy-pasted
per project.

This commit also migrates the inline TestLogger from
Microsoft.DotNet.HotReload.Client.Tests to consume the shared project,
which serves as the first reference consumer. Subsequent migration PRs
(DeltaApplier.Tests, Containers.UnitTests) will adopt the same project
reference instead of adding their own TestLogger/TestLoggerFactory copies.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 12, 2026
Replace the local Mocks/TestLogger.cs copy with a project reference to
the shared MSTest utilities project introduced in the Aspire migration
PR (dotnet#54722), keeping a single source of truth for the TestLogger
implementation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 12, 2026
Replace the local TestLoggerFactory.cs and InMemoryLoggerProvider.cs
copies with a project reference to the shared MSTest utilities project
introduced in the Aspire migration PR (dotnet#54722), keeping a single
source of truth for these logging helpers.

A global Using is added in the csproj so the existing consumer files
don't need per-file using directives.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 12, 2026
Follow-up to the pathfinder migration. containerize.UnitTests only uses xUnit
Fact/Theory/InlineData/Assert APIs - it does not use any types from
Microsoft.NET.TestFramework. So the project can drop its TestFramework
ProjectReference and switch to MSTest.Sdk in one self-contained PR.

Changes:
* test/containerize.UnitTests/containerize.UnitTests.csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true (opts the project out of the
    xUnit defaults in test/Directory.Build.targets - gate introduced in PR dotnet#54722).
  - Drop the ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* test/containerize.UnitTests/ParserTests.cs: xUnit -> MSTest mechanical
  conversion: [Fact]/[Theory] -> [TestMethod], [InlineData] -> [DataRow],
  add [TestClass], Assert.NotNull/Equal/Empty/Single ->
  IsNotNull/AreEqual/IsEmpty/HasCount(1, ...).

Verification: 9/9 tests pass on MTP in ~400 ms.

Stacks on top of PR dotnet#54722 (pathfinder). Merge after that one.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 12, 2026
Same pattern as containerize.UnitTests (dotnet#54723). This project's single test
file only uses xUnit Fact/Assert.Equal - no Microsoft.NET.TestFramework
types - so the TestFramework ProjectReference can be dropped and the
project switched to MSTest.Sdk in one self-contained change.

Changes:
* test/Microsoft.DotNet.ApiCompat.Tests/Microsoft.DotNet.ApiCompat.Tests.csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true.
  - Drop ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* test/Microsoft.DotNet.ApiCompat.Tests/RegexStringTransformerTests.cs:
  [Fact] -> [TestMethod], add [TestClass], Assert.Equal -> Assert.AreEqual.

Verification: 5/5 tests pass on MTP in ~250 ms.

Stacks on top of dotnet#54723 which stacks on dotnet#54722.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 12, 2026
… on MTP

Same pattern as previous migrations. None of the 6 test files used any
Microsoft.NET.TestFramework types - only xUnit primitives - so the
TestFramework ProjectReference can be dropped and the project switched to
MSTest.Sdk in one self-contained change.

Changes:
* test/Microsoft.AspNetCore.Watch.BrowserRefresh.Tests/csproj:
  - Use Sdk="MSTest.Sdk", set UseMSTestSdk=true.
  - Drop ProjectReference to Microsoft.NET.TestFramework (unused).
  - Drop OutputType=Exe (MSTest.Sdk handles it).
  - Add Microsoft.VisualStudio.TestTools.UnitTesting global using.
* 6 test files: xUnit -> MSTest mechanical conversion plus targeted fixes:
  - [Fact]/[Theory] -> [TestMethod], [InlineData] -> [DataRow], add [TestClass].
  - Assert.True/False/Null/NotNull/Empty/NotEmpty/Equal/NotEqual ->
    IsTrue/IsFalse/IsNull/IsNotNull/IsEmpty/IsNotEmpty/AreEqual/AreNotEqual.
  - Assert.Single(x) -> Assert.HasCount(1, x).
  - String Assert.Contains(needle, haystack) -> StringAssert.Contains(haystack, needle)
    (xUnit and MSTest argument orders are reversed).
  - One Assert.DoesNotContain(needle, str) -> Assert.IsFalse(str.Contains(needle)).
  - Assert.Collection in BrowserScriptMiddlewareTest expanded to inline
    Assert.HasCount + indexed AreEqual checks.
  - Assert.ThrowsAsync<T> -> Assert.ThrowsExactlyAsync<T>.
  - Assert.AreEqual on byte[]/int[] -> Assert.AreSequenceEqual (MSTEST0065:
    MSTest does not do element-wise equality on collections; the analyzer
    catches a real semantic difference vs xUnit).
  - StringValues (Microsoft.Extensions.Primitives) ambiguity with
    Assert.AreEqual<T> resolved by calling .ToString() at 5 call sites.
  - xUnit v3 TestContext.Current.CancellationToken -> CancellationToken.None
    (MSTest's TestContext.Current is experimental; tests do not actually
    require test-cancellation propagation).

Verification: 110/110 tests pass on MTP in ~480 ms.

Stacks on dotnet#54724 which stacks on dotnet#54723 which stacks on dotnet#54722.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evangelink added a commit to Evangelink/sdk that referenced this pull request Jun 12, 2026
…tain for strings

The migrate-xunit-to-mstest skill (.github/skills/migrate-xunit-to-mstest,
PR dotnet#54727) notes that MSTest 3.8+ added Assert.Contains(needle, str) /
Assert.DoesNotContain(needle, str) overloads for strings -- with the
natural (needle, haystack) argument order matching xUnit's
Assert.Contains. With the 4.3.0-preview MSTest.Sdk bump in dotnet#54722, these
are now available throughout the migration.

Replaced:
- StringAssert.Contains(haystack, needle)  -> Assert.Contains(needle, haystack)
- Assert.IsFalse(haystack.Contains(needle)) -> Assert.DoesNotContain(needle, haystack)

Touched files:
- BrowserRefreshMiddlewareTest.cs
- BrowserScriptMiddlewareTest.cs
- ResponseStreamWrapperCompressionTest.cs

Note: Assert.IsFalse(dict.ContainsKey(key)) call sites are unchanged
(no Assert.DoesNotContainKey API exists).

Verified: 110/110 tests still pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
Member Author

/azp run dotnet-sdk-public-ci

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants