diff --git a/Directory.Build.targets b/Directory.Build.targets
index 35de9c4323..725cc25fe1 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -72,6 +72,24 @@
+
+
+
+
+
+
+ false
+ false
+
+
+
+ false
+ false
+
+
<_TemplateProperties>Version=$(Version)
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 5ed8261b6b..183de48f9e 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -86,6 +86,8 @@
+
+
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index d4a4635809..23ea992129 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -286,7 +286,7 @@ stages:
- template: /eng/pipelines/steps/test-windows-configuration-tests.yml
parameters:
- # Enable only after the prerequisites in docs/affected-test-selection.md are satisfied.
+ # The package is wired, but collection remains disabled until its discovery child connects reliably.
enableAffectedTests: false
${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}:
affectedTestsMode: collect
diff --git a/docs/affected-test-selection.md b/docs/affected-test-selection.md
index 5cecec9659..2b675b493c 100644
--- a/docs/affected-test-selection.md
+++ b/docs/affected-test-selection.md
@@ -1,68 +1,55 @@
# Affected-test selection rollout
-This repository is prepared to adopt the experimental affected-test workflow from
+This repository is wired for the experimental affected-test workflow from
[dotnet/sdk#55574](https://github.com/dotnet/sdk/pull/55574). The workflow is Microsoft.Testing.Platform-only and
builds on the composable filter-provider support from
[testfx#10235](https://github.com/microsoft/testfx/pull/10235).
-The rollout is intentionally disabled. SDK `11.0.100-rc.1.26406.108` contains the affected-test commands but fails
-`dotnet tool restore` on clean agents because it predates
-[dotnet/sdk#55595](https://github.com/dotnet/sdk/pull/55595). The repository remains on the stable SDK until a fixed
-daily is published. The affected-test extension package and its public local-filesystem storage contract are also not
-available yet. Ordinary test commands therefore remain unchanged.
-
-## Prepared layout
-
-- `global.json` defines the repository-specific `test.affectedTests` change and instrumentation scopes.
-- The trusted main-branch Windows Release test is the future `--collect-test-map` entry point.
-- The Windows Release PR test is the future `--affected-tests` entry point.
-- The shared Windows test call site passes `enableAffectedTests: false` and selects the mode from the source branch. The
- inactive template branches restore the map through
- Azure Pipelines `Cache@2` and set `DOTNET_CLI_ENABLE_AFFECTED_TESTS=1` only for the affected-test commands.
-- `eng/validate-affected-tests.ps1` protects the disabled state and verifies that the public SDK gate and command names
- do not drift.
+The repository consumes `Microsoft.Testing.Extensions.AffectedTests` from the `test-tools` feed at the same version as
+`Microsoft.Testing.Extensions.CodeCoverage`, plus the provider-specific
+`Microsoft.Testing.Extensions.AffectedTests.Storage.AzureDevOps` package. The provider publishes versioned per-module
+mapping shards to the `TestFx_AffectedTestsMaps` artifact produced by pipeline definition 209. Its builder hook is
+registered by the repository's hand-authored MTP entry points.
+
+Selection remains disabled at the shared pipeline call site. Package
+`18.12.0-preview.26466.2` starts collection, but its internal `--list-tests` discovery child exits successfully before
+connecting to the extension's discovery pipe, so the parent reports
+`Test discovery child exited with code 0 before connecting.` and fails the run. Ordinary full-test CI remains active
+until a package containing a working discovery handshake is available.
+
+## CI layout
+
+- `global.json` defines the repository-specific `test.affectedTests` change policy and selects Azure DevOps artifact
+ storage for the public `microsoft.testfx` pipeline.
+- Once enabled, the trusted main-branch Windows Release test runs `--collect-test-map`.
+- Once enabled, the Windows Release PR test runs `--affected-tests`.
+- The package targets .NET 8 and later, so .NET Framework test modules continue to run in full before the affected-test
+ step. Collection, selection, and fallback commands are scoped to .NETCoreApp modules.
+- The shared Windows test call site selects the mode from the source branch, supplies Azure DevOps build identity and
+ the scoped system access token, and sets `DOTNET_CLI_ENABLE_AFFECTED_TESTS=1` only for affected-test commands.
+- `eng/validate-affected-tests.ps1` verifies the SDK gate, package reference, storage configuration, pipeline wiring,
+ command names, and fallbacks.
`DOTNET_CLI_TEST_AFFECTED_TESTS_MODE` is an SDK-to-extension authorization marker. Repository scripts and pipeline
definitions must not set it.
## Storage design
-The map should use the extension's local-filesystem provider rooted at
-`$(Pipeline.Workspace)\affected-test-map`. Azure Pipelines `Cache@2` transfers that directory between runs without
-credentials:
+The map uses the extension's Azure DevOps artifact provider:
-- trusted main builds can restore the previous map and publish a new immutable cache entry;
-- PR and fork-PR builds can read the target branch's cache scope but cannot write to it;
-- the cache prefix includes its manual compatibility version, OS, architecture, and configuration;
-- the unique build ID suffix lets every successful main collection publish a new map;
-- prefix restore selects the newest compatible map.
+- trusted main builds publish each module shard beneath the `TestFx_AffectedTestsMaps` artifact;
+- PR builds query successful builds from definition 209 and select the newest artifact whose baseline commit is an
+ ancestor of the PR checkout;
+- fork PRs receive no access token, so unavailable storage safely selects all tests rather than exposing credentials;
+- mapping identity includes the repository, module, target/runtime, test metadata, policy, and storage compatibility
+ fields, so incompatible shards are rejected conservatively.
-Azure Pipelines caches expire after seven days without activity. A cache miss is therefore an expected state, not a
-test failure: the PR lane runs the unchanged full test command. The same fallback runs when the extension rejects a
-missing, stale, or incompatible map, and scheduled or manual builds always keep full validation.
+A missing, stale, incompatible, or inaccessible artifact is an expected state, not a partial selection: the extension
+runs all tests. The pipeline's explicit full-test fallback remains for extension/process failures, while scheduled and
+manual builds always keep full validation.
Selected-test runs do not publish their partial coverage as the repository coverage report. Collection and full
fallback runs still publish complete coverage.
-Pipeline artifacts should contain only non-secret diagnostics or a mapping snapshot suitable for troubleshooting.
-They are not the cross-run source of truth because artifact lookup and retention are tied to individual builds.
-
-The `storage` property is deliberately absent from `test.affectedTests` until the extension package publishes the exact
-local-filesystem provider schema. Adding an invented provider or path setting now would create configuration that
-cannot be validated.
-
-## Activation checklist
-
-1. Update `global.json` to an SDK newer than `11.0.100-rc.1.26406.108` that contains dotnet/sdk#55595, then validate
- `dotnet tool restore` on a clean agent.
-2. Add the publicly available affected-test extension package through `Directory.Packages.props` and the test project
- infrastructure, following the repository's normal dependency-flow and package-source policy.
-3. Add `test.affectedTests.storage` using the package's published local-filesystem schema and point it at the Pipeline
- Cache directory.
-4. Update `affectedTestsCacheVersion` whenever the persisted map format or its compatibility dimensions change.
-5. Set `enableAffectedTests` to `true` in the shared Windows test call site so main builds collect maps and PR builds use
- them. Publish non-secret collection diagnostics as an Azure DevOps artifact.
-6. After a compatible map exists, validate PR selection. Keep the full test command available as an explicit rollback by
- setting `enableAffectedTests` back to `false`.
-7. Validate a documentation-only change, a product change with a narrow affected set, a force-all change, a missing or
- incompatible map, a fork PR without secrets, and a collection failure before making selection required.
+The one-switch rollback remains setting `enableAffectedTests` to `false`, which keeps the package and dormant storage
+configuration in place while restoring the ordinary full-test command.
diff --git a/eng/pipelines/steps/test-windows-configuration-tests.yml b/eng/pipelines/steps/test-windows-configuration-tests.yml
index f909c066b2..a8bd46ebdf 100644
--- a/eng/pipelines/steps/test-windows-configuration-tests.yml
+++ b/eng/pipelines/steps/test-windows-configuration-tests.yml
@@ -14,9 +14,6 @@ parameters:
- disabled
- collect
- run
-- name: affectedTestsCacheVersion
- type: string
- default: v1
steps:
# Because the build step is using -ci, restore is done in a local .packages directory.
@@ -36,43 +33,38 @@ steps:
# so report-azdo history queries no-op there; trusted branch builds exercise them end-to-end.
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
-# These branches are intentionally disabled at their call sites. They can be enabled only after the affected-test
-# extension package and its local-filesystem storage schema have flowed into this repository. The SDK owns
+# These branches implement affected-test collection and selection. The SDK owns
# DOTNET_CLI_TEST_AFFECTED_TESTS_MODE; pipelines must not set it.
-- ${{ if and(eq(parameters.enableAffectedTests, true), eq(parameters.affectedTestsMode, 'collect')) }}:
- - task: Cache@2
- displayName: Restore and publish affected-test map
- inputs:
- key: '"affected-tests" | "${{ parameters.affectedTestsCacheVersion }}" | "$(Agent.OS)" | "$(Agent.OSArchitecture)" | "$(_BuildConfig)" | "$(Build.BuildId)"'
- restoreKeys: |
- "affected-tests" | "${{ parameters.affectedTestsCacheVersion }}" | "$(Agent.OS)" | "$(Agent.OSArchitecture)" | "$(_BuildConfig)"
- path: '$(Pipeline.Workspace)\affected-test-map'
- cacheHitVar: AffectedTestsMapCacheRestored
+- ${{ if and(eq(parameters.enableAffectedTests, true), ne(parameters.affectedTestsMode, 'disabled')) }}:
+ # The affected-tests extension targets .NET 8 and later. Keep the .NET Framework coverage by running those
+ # test modules normally, then let the collect/run/fallback steps below handle only .NETCoreApp modules.
+ - script: |
+ dotnet test --solution TestFx.slnx -c $(_BuildConfig) --no-build -bl:$(BUILD.SOURCESDIRECTORY)\artifacts\TestResults\$(_BuildConfig)\TestNonCore.binlog -p:UsingDotNetTest=true -p:TestingPlatformCaptureOutput=false -p:AffectedTestsNonCoreOnly=true --show-test-results failed
+ name: TestNonCore
+ displayName: Test .NET Framework modules
condition: and(succeeded(), eq(variables._BuildConfig, 'Release'), ne(variables._XmlDocsOnly, 'true'))
+ env:
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+- ${{ if and(eq(parameters.enableAffectedTests, true), eq(parameters.affectedTestsMode, 'collect')) }}:
- script: |
echo ##vso[task.setvariable variable=PublishCoverageReport]true
- dotnet test --solution TestFx.slnx -c $(_BuildConfig) --no-build -bl:$(BUILD.SOURCESDIRECTORY)\artifacts\TestResults\$(_BuildConfig)\TestStep.binlog -p:UsingDotNetTest=true -p:TestingPlatformCaptureOutput=false --show-test-results failed --collect-test-map
+ dotnet test --solution TestFx.slnx -c $(_BuildConfig) --no-build -bl:$(BUILD.SOURCESDIRECTORY)\artifacts\TestResults\$(_BuildConfig)\TestCollect.binlog -p:UsingDotNetTest=true -p:TestingPlatformCaptureOutput=false -p:AffectedTestsCoreOnly=true --show-test-results failed --collect-test-map
name: Test
displayName: Test and collect affected-test map
condition: and(succeeded(), eq(variables._BuildConfig, 'Release'), ne(variables._XmlDocsOnly, 'true'))
env:
DOTNET_CLI_ENABLE_AFFECTED_TESTS: 1
+ CTS_ACCESSTOKEN: $(System.AccessToken)
+ CTS_COLLECTIONURI: $(System.CollectionUri)
+ CTS_TEMPDIRECTORY: $(Agent.TempDirectory)
+ CTS_BUILDID: $(Build.BuildId)
+ BUILD_CONTAINERID: $(Build.ContainerId)
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
- ${{ if and(eq(parameters.enableAffectedTests, true), eq(parameters.affectedTestsMode, 'run')) }}:
- - task: Cache@2
- displayName: Restore affected-test map
- inputs:
- key: '"affected-tests" | "${{ parameters.affectedTestsCacheVersion }}" | "$(Agent.OS)" | "$(Agent.OSArchitecture)" | "$(_BuildConfig)" | "$(Build.BuildId)"'
- restoreKeys: |
- "affected-tests" | "${{ parameters.affectedTestsCacheVersion }}" | "$(Agent.OS)" | "$(Agent.OSArchitecture)" | "$(_BuildConfig)"
- path: '$(Pipeline.Workspace)\affected-test-map'
- cacheHitVar: AffectedTestsMapCacheRestored
- condition: and(succeeded(), eq(variables._BuildConfig, 'Release'), ne(variables._XmlDocsOnly, 'true'), eq(variables['Build.Reason'], 'PullRequest'))
-
- pwsh: |
- dotnet test --solution TestFx.slnx -c $(_BuildConfig) --no-build -bl:$(BUILD.SOURCESDIRECTORY)\artifacts\TestResults\$(_BuildConfig)\TestStep.binlog -p:UsingDotNetTest=true -p:TestingPlatformCaptureOutput=false --show-test-results failed --affected-tests
+ dotnet test --solution TestFx.slnx -c $(_BuildConfig) --no-build -bl:$(BUILD.SOURCESDIRECTORY)\artifacts\TestResults\$(_BuildConfig)\TestAffected.binlog -p:UsingDotNetTest=true -p:TestingPlatformCaptureOutput=false -p:AffectedTestsCoreOnly=true --show-test-results failed --affected-tests
$exitCode = $LASTEXITCODE
if ($exitCode -eq 0) {
Write-Host "##vso[task.setvariable variable=AffectedTestsSucceeded]true"
@@ -88,9 +80,14 @@ steps:
exit 0
name: TestAffected
displayName: Test affected changes
- condition: and(succeeded(), eq(variables._BuildConfig, 'Release'), ne(variables._XmlDocsOnly, 'true'), eq(variables['Build.Reason'], 'PullRequest'), ne(variables['AffectedTestsMapCacheRestored'], 'false'))
+ condition: and(succeeded(), eq(variables._BuildConfig, 'Release'), ne(variables._XmlDocsOnly, 'true'), eq(variables['Build.Reason'], 'PullRequest'))
env:
DOTNET_CLI_ENABLE_AFFECTED_TESTS: 1
+ CTS_ACCESSTOKEN: $(System.AccessToken)
+ CTS_COLLECTIONURI: $(System.CollectionUri)
+ CTS_TEMPDIRECTORY: $(Agent.TempDirectory)
+ CTS_BUILDID: $(Build.BuildId)
+ BUILD_CONTAINERID: $(Build.ContainerId)
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
# Scheduled and manual runs keep their full-validation contract. PRs also fall back when the cache is absent or the
@@ -104,11 +101,11 @@ steps:
Remove-Item -Force
}
- dotnet test --solution TestFx.slnx -c $(_BuildConfig) --no-build -bl:$(BUILD.SOURCESDIRECTORY)\artifacts\TestResults\$(_BuildConfig)\TestStep.binlog -p:UsingDotNetTest=true -p:TestingPlatformCaptureOutput=false --show-test-results failed
+ dotnet test --solution TestFx.slnx -c $(_BuildConfig) --no-build -bl:$(BUILD.SOURCESDIRECTORY)\artifacts\TestResults\$(_BuildConfig)\TestFallback.binlog -p:UsingDotNetTest=true -p:TestingPlatformCaptureOutput=false -p:AffectedTestsCoreOnly=true --show-test-results failed
exit $LASTEXITCODE
name: Test
displayName: Test (affected-test fallback)
- condition: and(succeeded(), eq(variables._BuildConfig, 'Release'), ne(variables._XmlDocsOnly, 'true'), or(ne(variables['Build.Reason'], 'PullRequest'), eq(variables['AffectedTestsMapCacheRestored'], 'false'), ne(variables['AffectedTestsSucceeded'], 'true')))
+ condition: and(succeeded(), eq(variables._BuildConfig, 'Release'), ne(variables._XmlDocsOnly, 'true'), or(ne(variables['Build.Reason'], 'PullRequest'), ne(variables['AffectedTestsSucceeded'], 'true')))
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
diff --git a/eng/validate-affected-tests.ps1 b/eng/validate-affected-tests.ps1
index 2801e426cb..26c29f7cfa 100644
--- a/eng/validate-affected-tests.ps1
+++ b/eng/validate-affected-tests.ps1
@@ -15,9 +15,7 @@ if ($null -eq $affectedTests) {
foreach ($path in @(
"changes.ignore",
- "changes.forceAllTests",
- "instrumentation.include",
- "instrumentation.exclude"
+ "changes.forceAllTests"
)) {
$value = $affectedTests
foreach ($segment in $path.Split(".")) {
@@ -65,21 +63,70 @@ if ($affectedTestsEnabled -and $bootstrappedSdk -le $lastUnsupportedAffectedTest
throw "Affected-test execution requires an SDK newer than $lastUnsupportedAffectedTestsSdk with dotnet/sdk#55595."
}
-if ($affectedTestsEnabled -and $null -eq $affectedTests.storage) {
+if ($null -eq $affectedTests.storage) {
throw "Affected-test pipeline execution requires test.affectedTests.storage."
}
+if ($affectedTests.storage.type -ne "azureDevOpsArtifact" -or
+ $affectedTests.storage.project -ne "public" -or
+ $affectedTests.storage.buildDefinitionId -ne 209 -or
+ $affectedTests.storage.artifactName -ne "TestFx_AffectedTestsMaps") {
+ throw "Affected-test pipeline execution must use the testfx Azure DevOps artifact provider configuration."
+}
+
+$directoryPackagesPath = Join-Path $repoRoot "Directory.Packages.props"
+$directoryPackages = Get-Content -LiteralPath $directoryPackagesPath -Raw
+if (-not $directoryPackages.Contains(
+ '')) {
+ throw "Directory.Packages.props must align Microsoft.Testing.Extensions.AffectedTests with the CodeCoverage dependency."
+}
+if (-not $directoryPackages.Contains(
+ '')) {
+ throw "Directory.Packages.props must align the Azure DevOps affected-tests provider with the CodeCoverage dependency."
+}
+
+$directoryBuildTargetsPath = Join-Path $repoRoot "Directory.Build.targets"
+$directoryBuildTargets = Get-Content -LiteralPath $directoryBuildTargetsPath -Raw
+if (-not $directoryBuildTargets.Contains(
+ ' Main(string[] args)
{
ITestApplicationBuilder testApplicationBuilder = await TestApplication.CreateBuilderAsync(args);
+ Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(testApplicationBuilder, args);
testApplicationBuilder.AddMSTest(() => [Assembly.GetEntryAssembly()!]);
testApplicationBuilder.AddCtrfReportProvider();
using ITestApplication app = await testApplicationBuilder.BuildAsync();
diff --git a/samples/FSharpPlayground/Program.fs b/samples/FSharpPlayground/Program.fs
index 85edb3719a..62033b661f 100644
--- a/samples/FSharpPlayground/Program.fs
+++ b/samples/FSharpPlayground/Program.fs
@@ -16,6 +16,7 @@ module Program =
task {
let! testApplicationBuilder = TestApplication.CreateBuilderAsync(args)
+ Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(testApplicationBuilder, args)
// Test MSTest
let entryAssembly =
diff --git a/samples/NUnitPlayground/Program.cs b/samples/NUnitPlayground/Program.cs
index 3332fbb600..a3076bde31 100644
--- a/samples/NUnitPlayground/Program.cs
+++ b/samples/NUnitPlayground/Program.cs
@@ -9,6 +9,7 @@
Environment.SetEnvironmentVariable("DOTNET_CLI_TELEMETRY_OPTOUT", "1");
ITestApplicationBuilder testApplicationBuilder = await TestApplication.CreateBuilderAsync(args);
+Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(testApplicationBuilder, args);
testApplicationBuilder.AddNUnit(() => [Assembly.GetEntryAssembly()]);
using ITestApplication testApplication = await testApplicationBuilder.BuildAsync();
return await testApplication.RunAsync();
diff --git a/samples/Playground/Program.cs b/samples/Playground/Program.cs
index 202470e482..083b94108b 100644
--- a/samples/Playground/Program.cs
+++ b/samples/Playground/Program.cs
@@ -36,6 +36,10 @@ public static async Task Main(string[] args)
ITestApplicationBuilder testApplicationBuilder = await TestApplication.CreateBuilderAsync(args);
+#if NET8_0_OR_GREATER
+ Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(testApplicationBuilder, args);
+#endif
+
// Test MSTest
testApplicationBuilder.AddMSTest(() => [Assembly.GetEntryAssembly()!]);
testApplicationBuilder.AddCrashDumpProvider();
diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/Program.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/Program.cs
index 40fda96bff..8fa6f3e048 100644
--- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/Program.cs
+++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/Program.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Testing.Extensions;
@@ -15,6 +15,10 @@
ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args);
+#if NET8_0_OR_GREATER
+Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(builder, args);
+#endif
+
builder.AddMSTest(() => [Assembly.GetEntryAssembly()!]);
#if ENABLE_CODECOVERAGE
builder.AddCodeCoverageProvider();
diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Program.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Program.cs
index 6ab5309331..39d0f4aaf7 100644
--- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Program.cs
+++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Program.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Testing.Extensions;
@@ -15,6 +15,10 @@
ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args);
+#if NET8_0_OR_GREATER
+Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(builder, args);
+#endif
+
builder.AddMSTest(() => [Assembly.GetEntryAssembly()!]);
#if ENABLE_CODECOVERAGE
builder.AddCodeCoverageProvider();
diff --git a/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/Program.cs b/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/Program.cs
index 474a775f52..4ce9445d15 100644
--- a/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/Program.cs
+++ b/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/Program.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Testing.Extensions;
@@ -10,6 +10,10 @@
ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args);
+#if NET8_0_OR_GREATER
+Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(builder, args);
+#endif
+
#if ENABLE_CODECOVERAGE
builder.AddCodeCoverageProvider();
#endif
diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/Program.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/Program.cs
index 01c0e36bb7..5016065a32 100644
--- a/test/UnitTests/MSTest.Analyzers.UnitTests/Program.cs
+++ b/test/UnitTests/MSTest.Analyzers.UnitTests/Program.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Testing.Extensions;
@@ -13,6 +13,10 @@
// DebuggerUtility.AttachVSToCurrentProcess();
ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args);
+#if NET8_0_OR_GREATER
+Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(builder, args);
+#endif
+
builder.AddMSTest(() => [Assembly.GetEntryAssembly()!]);
#if ENABLE_CODECOVERAGE
builder.AddCodeCoverageProvider();
diff --git a/test/UnitTests/MSTest.SelfRealExamples.UnitTests/Program.cs b/test/UnitTests/MSTest.SelfRealExamples.UnitTests/Program.cs
index daddb48f25..89dcf9b50d 100644
--- a/test/UnitTests/MSTest.SelfRealExamples.UnitTests/Program.cs
+++ b/test/UnitTests/MSTest.SelfRealExamples.UnitTests/Program.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Testing.Extensions;
@@ -10,6 +10,10 @@
ITestApplicationBuilder testApplicationBuilder = await TestApplication.CreateBuilderAsync(args);
+#if NET8_0_OR_GREATER
+Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(testApplicationBuilder, args);
+#endif
+
testApplicationBuilder.AddMSTest(() => [Assembly.GetEntryAssembly()!]);
testApplicationBuilder.AddTrxReportProvider();
testApplicationBuilder.AddJUnitReportProvider();
diff --git a/test/UnitTests/MSTest.SourceGeneration.UnitTests/Program.cs b/test/UnitTests/MSTest.SourceGeneration.UnitTests/Program.cs
index c1b8076a92..808cff0c42 100644
--- a/test/UnitTests/MSTest.SourceGeneration.UnitTests/Program.cs
+++ b/test/UnitTests/MSTest.SourceGeneration.UnitTests/Program.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Testing.Extensions;
@@ -7,6 +7,9 @@
using OpenTelemetry.Trace;
ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args);
+#if NET8_0_OR_GREATER
+Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(builder, args);
+#endif
builder.AddMSTest(() => [Assembly.GetEntryAssembly()!]);
#if ENABLE_CODECOVERAGE
diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Program.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Program.cs
index 474a775f52..4ce9445d15 100644
--- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Program.cs
+++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Program.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Testing.Extensions;
@@ -10,6 +10,10 @@
ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args);
+#if NET8_0_OR_GREATER
+Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(builder, args);
+#endif
+
#if ENABLE_CODECOVERAGE
builder.AddCodeCoverageProvider();
#endif
diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Program.cs b/test/UnitTests/MSTestAdapter.UnitTests/Program.cs
index 474a775f52..4ce9445d15 100644
--- a/test/UnitTests/MSTestAdapter.UnitTests/Program.cs
+++ b/test/UnitTests/MSTestAdapter.UnitTests/Program.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Testing.Extensions;
@@ -10,6 +10,10 @@
ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args);
+#if NET8_0_OR_GREATER
+Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(builder, args);
+#endif
+
#if ENABLE_CODECOVERAGE
builder.AddCodeCoverageProvider();
#endif
diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Program.cs b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Program.cs
index 26c0e5d9bf..6a6f8e717e 100644
--- a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Program.cs
+++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Program.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Testing.Extensions;
@@ -12,6 +12,10 @@
ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args);
+#if NET8_0_OR_GREATER
+Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(builder, args);
+#endif
+
builder.AddMSTest(() => [Assembly.GetEntryAssembly()!]);
#if ENABLE_CODECOVERAGE
builder.AddCodeCoverageProvider();
diff --git a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Program.cs b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Program.cs
index 281a69986d..5b737ea3c9 100644
--- a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Program.cs
+++ b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Program.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Testing.Extensions;
@@ -18,6 +18,10 @@
ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args);
+#if NET8_0_OR_GREATER
+Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(builder, args);
+#endif
+
builder.AddMSTest(() => [Assembly.GetEntryAssembly()!]);
#if !NATIVE_AOT
diff --git a/test/UnitTests/Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTests/Program.cs b/test/UnitTests/Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTests/Program.cs
index 87d438ae64..fe2b08b067 100644
--- a/test/UnitTests/Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTests/Program.cs
+++ b/test/UnitTests/Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTests/Program.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Testing.Extensions;
@@ -15,6 +15,10 @@
ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args);
+#if NET8_0_OR_GREATER
+Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(builder, args);
+#endif
+
builder.AddMSTest(() => [Assembly.GetEntryAssembly()!]);
#if ENABLE_CODECOVERAGE
diff --git a/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Program.cs b/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Program.cs
index 242506a101..08d923ebaf 100644
--- a/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Program.cs
+++ b/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Program.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Testing.Extensions;
@@ -10,6 +10,9 @@
// DebuggerUtility.AttachVSToCurrentProcess();
ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args);
+#if NET8_0_OR_GREATER
+Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(builder, args);
+#endif
builder.AddMSTest(() => [Assembly.GetEntryAssembly()!]);
#if ENABLE_CODECOVERAGE
builder.AddCodeCoverageProvider();
diff --git a/test/UnitTests/Microsoft.Testing.Platform.ServerMode.Client.Sources.UnitTests/Program.cs b/test/UnitTests/Microsoft.Testing.Platform.ServerMode.Client.Sources.UnitTests/Program.cs
index da6323438a..8f3a681e26 100644
--- a/test/UnitTests/Microsoft.Testing.Platform.ServerMode.Client.Sources.UnitTests/Program.cs
+++ b/test/UnitTests/Microsoft.Testing.Platform.ServerMode.Client.Sources.UnitTests/Program.cs
@@ -17,6 +17,10 @@
ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args);
+#if NET8_0_OR_GREATER
+Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(builder, args);
+#endif
+
builder.AddMSTest(() => [Assembly.GetEntryAssembly()!]);
// Register the same platform extensions every other testfx unit-test app registers. CI runs each test
diff --git a/test/UnitTests/Microsoft.Testing.Platform.TerminalReporterContract.UnitTests/Program.cs b/test/UnitTests/Microsoft.Testing.Platform.TerminalReporterContract.UnitTests/Program.cs
index 87d438ae64..fe2b08b067 100644
--- a/test/UnitTests/Microsoft.Testing.Platform.TerminalReporterContract.UnitTests/Program.cs
+++ b/test/UnitTests/Microsoft.Testing.Platform.TerminalReporterContract.UnitTests/Program.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Testing.Extensions;
@@ -15,6 +15,10 @@
ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args);
+#if NET8_0_OR_GREATER
+Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(builder, args);
+#endif
+
builder.AddMSTest(() => [Assembly.GetEntryAssembly()!]);
#if ENABLE_CODECOVERAGE
diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Program.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Program.cs
index f46c9fc5cf..601bd2ba3b 100644
--- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Program.cs
+++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Program.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Testing.Extensions;
@@ -16,6 +16,10 @@
// DebuggerUtility.AttachVSToCurrentProcess();
ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args);
+#if NET8_0_OR_GREATER
+Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(builder, args);
+#endif
+
builder.AddMSTest(() => [Assembly.GetEntryAssembly()!]);
#if ENABLE_CODECOVERAGE
diff --git a/test/UnitTests/TestFramework.UnitTests/Program.cs b/test/UnitTests/TestFramework.UnitTests/Program.cs
index 474a775f52..4ce9445d15 100644
--- a/test/UnitTests/TestFramework.UnitTests/Program.cs
+++ b/test/UnitTests/TestFramework.UnitTests/Program.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Testing.Extensions;
@@ -10,6 +10,10 @@
ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args);
+#if NET8_0_OR_GREATER
+Microsoft.Testing.Extensions.AffectedTests.TestingPlatformBuilderHook.AddExtensions(builder, args);
+#endif
+
#if ENABLE_CODECOVERAGE
builder.AddCodeCoverageProvider();
#endif