Migrate Microsoft.NET.Build.Containers.UnitTests to MSTest.Sdk#54732
Migrate Microsoft.NET.Build.Containers.UnitTests to MSTest.Sdk#54732Evangelink wants to merge 13 commits into
Conversation
|
Replaced the manual Also refreshed the related comments in |
|
Made The new (Applied to all 9 stacked PRs since they share these plumbing files.) |
|
Replaced the custom |
|
Round 3: moved The Using is now global for any test project ( Deviation from your literal suggestion: I left the |
There was a problem hiding this comment.
Pull request overview
Migrates Microsoft.NET.Build.Containers.UnitTests from xUnit to MSTest.Sdk (Microsoft.Testing.Platform) and updates the repo’s Helix/xUnit-runner infrastructure to correctly dispatch MTP-based test projects. Also introduces MSTest-friendly logging replacements for ITestOutputHelper and adjusts Microsoft.NET.Build.Containers.IntegrationTests to no longer depend on the unit test project.
Changes:
- Convert
Microsoft.NET.Build.Containers.UnitTeststest suite from xUnit attributes/assertions to MSTest equivalents and add MSTest-oriented test logging helpers. - Update Helix work item creation + xunit-runner targets to detect MTP projects and invoke them via
dotnet execwith MTP CLI switches (and TRX reporting when supported). - Remove
IntegrationTests’ dependency on the unit test project and reintroduce Docker-availability xUnit attributes locally for integration tests.
Show a summary per file
| File | Description |
|---|---|
| test/xunit-runner/XUnitRunner.targets | Collects additional per-project metadata for Helix dispatch (MTP/TRX capability). |
| test/xunit-runner/XUnitPublish.targets | Adds MSBuild query targets for MTP detection and TRX extension detection. |
| test/HelixTasks/SDKCustomCreateXUnitWorkItemsWithTestExclusion.cs | Emits different Helix execution commands for MTP vs VSTest/xUnit paths. |
| test/Directory.Build.targets | Gates xUnit-only global usings and adds AwesomeAssertions for MSTest.Sdk projects. |
| test/Microsoft.NET.Build.Containers.UnitTests/Microsoft.NET.Build.Containers.UnitTests.csproj | Switches project SDK to MSTest.Sdk and adjusts references. |
| test/Microsoft.NET.Build.Containers.UnitTests/TestLoggerFactory.cs | New MSTest-friendly logger factory (TestContext + console). |
| test/Microsoft.NET.Build.Containers.UnitTests/InMemoryLoggerProvider.cs | New in-memory logger provider used by logging assertions. |
| test/Microsoft.NET.Build.Containers.UnitTests/Resources/ResourceTests.cs | Migrates tests from xUnit to MSTest assertions/attributes. |
| test/Microsoft.NET.Build.Containers.UnitTests/RegistryTests.cs | Migrates tests to MSTest + TestContext-based logging. |
| test/Microsoft.NET.Build.Containers.UnitTests/ImageIndexGeneratorTests.cs | Migrates tests from xUnit to MSTest. |
| test/Microsoft.NET.Build.Containers.UnitTests/ImageConfigTests.cs | Migrates tests from xUnit to MSTest. |
| test/Microsoft.NET.Build.Containers.UnitTests/ImageBuilderTests.cs | Migrates tests from xUnit to MSTest and adjusts assertions. |
| test/Microsoft.NET.Build.Containers.UnitTests/FallbackToHttpMessageHandlerTests.cs | Migrates to MSTest and uses TestContext.CancellationToken. |
| test/Microsoft.NET.Build.Containers.UnitTests/DockerDaemonTests.cs | Replaces xUnit Docker-availability gating with MSTest condition attributes. |
| test/Microsoft.NET.Build.Containers.UnitTests/DockerAvailableUtils.cs | Replaces xUnit attributes with MSTest ConditionBaseAttribute implementations. |
| test/Microsoft.NET.Build.Containers.UnitTests/DigestUtilsTests.cs | Migrates tests from xUnit to MSTest. |
| test/Microsoft.NET.Build.Containers.UnitTests/DescriptorTests.cs | Migrates tests from xUnit to MSTest. |
| test/Microsoft.NET.Build.Containers.UnitTests/CreateNewImageTests.cs | Migrates parameterized tests from xUnit to MSTest DataRow. |
| test/Microsoft.NET.Build.Containers.UnitTests/ContentStoreTests.cs | Migrates tests from xUnit to MSTest. |
| test/Microsoft.NET.Build.Containers.UnitTests/ContainerHelpersTests.cs | Migrates tests from xUnit to MSTest. |
| test/Microsoft.NET.Build.Containers.UnitTests/AuthHandshakeMessageHandlerTests.cs | Migrates to MSTest (incl. DynamicData + cancellation token). |
| test/Microsoft.NET.Build.Containers.IntegrationTests/Microsoft.NET.Build.Containers.IntegrationTests.csproj | Removes reference to unit test project. |
| test/Microsoft.NET.Build.Containers.IntegrationTests/ParseContainerPropertiesTests.cs | Removes UnitTests using after decoupling. |
| test/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs | Removes UnitTests using after decoupling. |
| test/Microsoft.NET.Build.Containers.IntegrationTests/DockerRegistryTests.cs | Removes UnitTests using after decoupling. |
| test/Microsoft.NET.Build.Containers.IntegrationTests/CreateNewImageTests.cs | Removes UnitTests using after decoupling. |
| test/Microsoft.NET.Build.Containers.IntegrationTests/CreateImageIndexTests.cs | Removes UnitTests using after decoupling. |
| test/Microsoft.NET.Build.Containers.IntegrationTests/DockerAvailableAttributes.cs | Adds xUnit-specific Docker availability attributes (replacement for removed UnitTests ones). |
| test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/Microsoft.DotNet.HotReload.Watch.Aspire.Tests.csproj | Switches project SDK to MSTest.Sdk and simplifies references. |
| 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 while keeping FluentAssertions checks. |
| 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. |
| test/dotnet-watch.Tests/dotnet-watch.Tests.csproj | Adds reference needed for Aspire launcher integration execution. |
| test/dotnet-watch.Tests/Aspire/PipeUtilities.cs | New helper for pipe-based status event reading in Aspire-related tests. |
| test/dotnet-watch.Tests/Aspire/AspireLauncherIntegrationTests.cs | Renames test class to reflect integration test behavior. |
| src/Dotnet.Watch/Watch.Aspire/Properties/AssemblyInfo.cs | Adds InternalsVisibleTo for dotnet-watch.Tests. |
| global.json | Adds a toolset version pin for MSTest.Sdk. |
Copilot's findings
- Files reviewed: 37/38 changed files
- Comments generated: 4
| <TargetFramework>$(SdkTargetFramework)</TargetFramework> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <IsPackable>false</IsPackable> | ||
| <IsTestProject>true</IsTestProject> | ||
| <StrongNameKeyId>MicrosoftShared</StrongNameKeyId> |
| <TargetFramework>$(SdkTargetFramework)</TargetFramework> | ||
| <OutputType>Exe</OutputType> | ||
| <RootNamespace>Microsoft.DotNet.Watch.Aspire.UnitTests</RootNamespace> | ||
| <StrongNameKeyId>MicrosoftAspNetCore</StrongNameKeyId> |
| public void CheckIfGoogleArtifactRegistry(string registryName, bool isECR) | ||
| { | ||
| ILogger logger = _loggerFactory.CreateLogger(nameof(CheckIfGoogleArtifactRegistry)); | ||
| Registry registry = new(registryName, logger, RegistryMode.Push); | ||
| Assert.Equal(isECR, registry.IsGoogleArtifactRegistry); | ||
| Assert.AreEqual(isECR, registry.IsGoogleArtifactRegistry); |
| public ILogger CreateLogger(string categoryName) | ||
| { | ||
| ILoggerFactory loggerFactory = LoggerFactory.Create(builder => | ||
| { | ||
| builder.SetMinimumLevel(LogLevel.Trace); |
…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>
1dafe8b to
e252e4c
Compare
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>
- Switch SDK to MSTest.Sdk; set UseMSTestSdk=true to opt out of test/Directory.Build.targets xUnit defaults. - Replace [Fact]/[Theory] + [InlineData]/[MemberData] with MSTest attributes. - Replace ITestOutputHelper-based logging with TestContext-backed test logging helpers. - Convert xUnit assertions to MSTest assertions and preserve dynamic Docker skips with MSTest conditions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Containers.UnitTests project was migrated to MSTest.Sdk in this PR, which brought a transitive 'global using Microsoft.VisualStudio.TestTools.UnitTesting;' into the still-xUnit IntegrationTests project via its ProjectReference, breaking every Assert call with CS0104 (ambiguous between MSTest and Xunit Assert types). - Remove the ProjectReference: IntegrationTests no longer used any types from the UnitTests assembly. - Add DockerAvailableFactAttribute and DockerAvailableTheoryAttribute locally in the IntegrationTests namespace (xUnit-flavored), restoring the API that the previous shared attributes provided. - Drop the now-unused 'using Microsoft.NET.Build.Containers.UnitTests;' from 5 test files. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…Sdk)
MSTest.Sdk already sets $(UsingMSTestSdk)=true in its Sdk.props before
Directory.Build.props is evaluated, so the custom <UseMSTestSdk>true</UseMSTestSdk>
opt-in property is redundant. This change:
- Removes <UseMSTestSdk>true</UseMSTestSdk> from MSTest.Sdk csproj(s).
- Renames $(UseMSTestSdk) -> $(UsingMSTestSdk) in test/Directory.Build.targets
(the xUnit-defaults gating condition) and in xunit-runner/{XUnitPublish,XUnitRunner}.targets
(Helix MTP dispatcher detection).
Replaces [TestInitialize] with constructor injection of TestContext (MSTest 3.6+), allowing _loggerFactory to become readonly. Aligns with the writing-mstest-tests skill guidance: "Always initialize in the constructor" / "Use [TestInitialize] only for async initialization". Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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>
e252e4c to
1c3c44a
Compare
|
@Evangelink, please ping me directly when this is ready for review, as I am muting all of these threads due to the high number of force push notifications. |
|
/azp run dotnet-sdk-public-ci |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run dotnet-sdk-public-ci |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run dotnet-sdk-public-ci |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run dotnet-sdk-public-ci |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run dotnet-sdk-public-ci |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run dotnet-sdk-public-ci |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run dotnet-sdk-public-ci |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run dotnet-sdk-public-ci |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run dotnet-sdk-public-ci |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run dotnet-sdk-public-ci |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run dotnet-sdk-public-ci |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run dotnet-sdk-public-ci |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Summary
Validation
Q:\src\sdk\.dotnet\dotnet.exe build test\Microsoft.NET.Build.Containers.UnitTests\Microsoft.NET.Build.Containers.UnitTests.csproj --nologoQ:\src\sdk\.dotnet\dotnet.exe exec artifacts\bin\Microsoft.NET.Build.Containers.UnitTests\Debug\net11.0\Microsoft.NET.Build.Containers.UnitTests.dllNo microsoft/testfx issues filed.