diff --git a/test/TestAssets/TestProjects/MultiTestProjectSolutionWithPlatforms/MultiTestProjectSolutionWithPlatforms.slnx b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithPlatforms/MultiTestProjectSolutionWithPlatforms.slnx
new file mode 100644
index 000000000000..1aaea6e63609
--- /dev/null
+++ b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithPlatforms/MultiTestProjectSolutionWithPlatforms.slnx
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/TestAssets/TestProjects/MultiTestProjectSolutionWithPlatforms/OtherTestProject/OtherTestProject.csproj b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithPlatforms/OtherTestProject/OtherTestProject.csproj
new file mode 100644
index 000000000000..9857918867b1
--- /dev/null
+++ b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithPlatforms/OtherTestProject/OtherTestProject.csproj
@@ -0,0 +1,17 @@
+
+
+
+
+ $(CurrentTargetFramework)
+ Exe
+
+ enable
+ enable
+
+ false
+
+
+
+
+
+
diff --git a/test/TestAssets/TestProjects/MultiTestProjectSolutionWithPlatforms/OtherTestProject/Program.cs b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithPlatforms/OtherTestProject/Program.cs
new file mode 100644
index 000000000000..8400bde6b706
--- /dev/null
+++ b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithPlatforms/OtherTestProject/Program.cs
@@ -0,0 +1,59 @@
+using Microsoft.Testing.Platform.Builder;
+using Microsoft.Testing.Platform.Capabilities.TestFramework;
+using Microsoft.Testing.Platform.Extensions.Messages;
+using Microsoft.Testing.Platform.Extensions.TestFramework;
+
+for (int i = 0; i < 3; i++)
+{
+ Console.WriteLine(new string('a', 10000));
+ Console.Error.WriteLine(new string('e', 10000));
+}
+
+var testApplicationBuilder = await TestApplication.CreateBuilderAsync(args);
+
+testApplicationBuilder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_, __) => new DummyTestAdapter());
+
+using var testApplication = await testApplicationBuilder.BuildAsync();
+return await testApplication.RunAsync();
+
+public class DummyTestAdapter : ITestFramework, IDataProducer
+{
+ public string Uid => nameof(DummyTestAdapter);
+
+ public string Version => "2.0.0";
+
+ public string DisplayName => nameof(DummyTestAdapter);
+
+ public string Description => nameof(DummyTestAdapter);
+
+ public Task IsEnabledAsync() => Task.FromResult(true);
+
+ public Type[] DataTypesProduced => new[] {
+ typeof(TestNodeUpdateMessage)
+ };
+
+ public Task CreateTestSessionAsync(CreateTestSessionContext context)
+ => Task.FromResult(new CreateTestSessionResult() { IsSuccess = true });
+
+ public Task CloseTestSessionAsync(CloseTestSessionContext context)
+ => Task.FromResult(new CloseTestSessionResult() { IsSuccess = true });
+
+ public async Task ExecuteRequestAsync(ExecuteRequestContext context)
+ {
+ await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, new TestNode()
+ {
+ Uid = "Test1",
+ DisplayName = "Test1",
+ Properties = new PropertyBag(new PassedTestNodeStateProperty("OK")),
+ }));
+
+ await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, new TestNode()
+ {
+ Uid = "Test2",
+ DisplayName = "Test2",
+ Properties = new PropertyBag(new SkippedTestNodeStateProperty("skipped")),
+ }));
+
+ context.Complete();
+ }
+}
\ No newline at end of file
diff --git a/test/TestAssets/TestProjects/MultiTestProjectSolutionWithPlatforms/TestProject/Program.cs b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithPlatforms/TestProject/Program.cs
new file mode 100644
index 000000000000..e5bd6d0e05b0
--- /dev/null
+++ b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithPlatforms/TestProject/Program.cs
@@ -0,0 +1,66 @@
+using Microsoft.Testing.Platform.Builder;
+using Microsoft.Testing.Platform.Capabilities.TestFramework;
+using Microsoft.Testing.Platform.Extensions.Messages;
+using Microsoft.Testing.Platform.Extensions.TestFramework;
+
+for (int i = 0; i < 3; i++)
+{
+ Console.WriteLine(new string('a', 10000));
+ Console.Error.WriteLine(new string('e', 10000));
+}
+
+var testApplicationBuilder = await TestApplication.CreateBuilderAsync(args);
+
+testApplicationBuilder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_, __) => new DummyTestAdapter());
+
+using var testApplication = await testApplicationBuilder.BuildAsync();
+return await testApplication.RunAsync();
+
+public class DummyTestAdapter : ITestFramework, IDataProducer
+{
+ public string Uid => nameof(DummyTestAdapter);
+
+ public string Version => "2.0.0";
+
+ public string DisplayName => nameof(DummyTestAdapter);
+
+ public string Description => nameof(DummyTestAdapter);
+
+ public Task IsEnabledAsync() => Task.FromResult(true);
+
+ public Type[] DataTypesProduced => new[] {
+ typeof(TestNodeUpdateMessage)
+ };
+
+ public Task CreateTestSessionAsync(CreateTestSessionContext context)
+ => Task.FromResult(new CreateTestSessionResult() { IsSuccess = true });
+
+ public Task CloseTestSessionAsync(CloseTestSessionContext context)
+ => Task.FromResult(new CloseTestSessionResult() { IsSuccess = true });
+
+ public async Task ExecuteRequestAsync(ExecuteRequestContext context)
+ {
+ await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, new TestNode()
+ {
+ Uid = "Test0",
+ DisplayName = "Test0",
+ Properties = new PropertyBag(new PassedTestNodeStateProperty("OK")),
+ }));
+
+ await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, new TestNode()
+ {
+ Uid = "Test1",
+ DisplayName = "Test1",
+ Properties = new PropertyBag(new SkippedTestNodeStateProperty("OK skipped!")),
+ }));
+
+ await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, new TestNode()
+ {
+ Uid = "Test2",
+ DisplayName = "Test2",
+ Properties = new PropertyBag(new FailedTestNodeStateProperty(new Exception("this is a failed test"), "not OK")),
+ }));
+
+ context.Complete();
+ }
+}
\ No newline at end of file
diff --git a/test/TestAssets/TestProjects/MultiTestProjectSolutionWithPlatforms/TestProject/TestProject.csproj b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithPlatforms/TestProject/TestProject.csproj
new file mode 100644
index 000000000000..9857918867b1
--- /dev/null
+++ b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithPlatforms/TestProject/TestProject.csproj
@@ -0,0 +1,17 @@
+
+
+
+
+ $(CurrentTargetFramework)
+ Exe
+
+ enable
+ enable
+
+ false
+
+
+
+
+
+
diff --git a/test/TestAssets/TestProjects/MultiTestProjectSolutionWithPlatforms/global.json b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithPlatforms/global.json
new file mode 100644
index 000000000000..9009caf0ba8f
--- /dev/null
+++ b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithPlatforms/global.json
@@ -0,0 +1,5 @@
+{
+ "test": {
+ "runner": "Microsoft.Testing.Platform"
+ }
+}
diff --git a/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/MultiTestProjectSolutionWithSharedProject.slnx b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/MultiTestProjectSolutionWithSharedProject.slnx
new file mode 100644
index 000000000000..3aa9eb0b0e3c
--- /dev/null
+++ b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/MultiTestProjectSolutionWithSharedProject.slnx
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/OtherTestProject/OtherTestProject.csproj b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/OtherTestProject/OtherTestProject.csproj
new file mode 100644
index 000000000000..9857918867b1
--- /dev/null
+++ b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/OtherTestProject/OtherTestProject.csproj
@@ -0,0 +1,17 @@
+
+
+
+
+ $(CurrentTargetFramework)
+ Exe
+
+ enable
+ enable
+
+ false
+
+
+
+
+
+
diff --git a/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/OtherTestProject/Program.cs b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/OtherTestProject/Program.cs
new file mode 100644
index 000000000000..8400bde6b706
--- /dev/null
+++ b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/OtherTestProject/Program.cs
@@ -0,0 +1,59 @@
+using Microsoft.Testing.Platform.Builder;
+using Microsoft.Testing.Platform.Capabilities.TestFramework;
+using Microsoft.Testing.Platform.Extensions.Messages;
+using Microsoft.Testing.Platform.Extensions.TestFramework;
+
+for (int i = 0; i < 3; i++)
+{
+ Console.WriteLine(new string('a', 10000));
+ Console.Error.WriteLine(new string('e', 10000));
+}
+
+var testApplicationBuilder = await TestApplication.CreateBuilderAsync(args);
+
+testApplicationBuilder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_, __) => new DummyTestAdapter());
+
+using var testApplication = await testApplicationBuilder.BuildAsync();
+return await testApplication.RunAsync();
+
+public class DummyTestAdapter : ITestFramework, IDataProducer
+{
+ public string Uid => nameof(DummyTestAdapter);
+
+ public string Version => "2.0.0";
+
+ public string DisplayName => nameof(DummyTestAdapter);
+
+ public string Description => nameof(DummyTestAdapter);
+
+ public Task IsEnabledAsync() => Task.FromResult(true);
+
+ public Type[] DataTypesProduced => new[] {
+ typeof(TestNodeUpdateMessage)
+ };
+
+ public Task CreateTestSessionAsync(CreateTestSessionContext context)
+ => Task.FromResult(new CreateTestSessionResult() { IsSuccess = true });
+
+ public Task CloseTestSessionAsync(CloseTestSessionContext context)
+ => Task.FromResult(new CloseTestSessionResult() { IsSuccess = true });
+
+ public async Task ExecuteRequestAsync(ExecuteRequestContext context)
+ {
+ await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, new TestNode()
+ {
+ Uid = "Test1",
+ DisplayName = "Test1",
+ Properties = new PropertyBag(new PassedTestNodeStateProperty("OK")),
+ }));
+
+ await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, new TestNode()
+ {
+ Uid = "Test2",
+ DisplayName = "Test2",
+ Properties = new PropertyBag(new SkippedTestNodeStateProperty("skipped")),
+ }));
+
+ context.Complete();
+ }
+}
\ No newline at end of file
diff --git a/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/SharedProject/SharedClass.cs b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/SharedProject/SharedClass.cs
new file mode 100644
index 000000000000..760b66570ec0
--- /dev/null
+++ b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/SharedProject/SharedClass.cs
@@ -0,0 +1,7 @@
+namespace SharedProject
+{
+ public class SharedClass
+ {
+ public static string GetMessage() => "Hello from shared project";
+ }
+}
diff --git a/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/SharedProject/SharedProject.projitems b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/SharedProject/SharedProject.projitems
new file mode 100644
index 000000000000..34d010f9a5f0
--- /dev/null
+++ b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/SharedProject/SharedProject.projitems
@@ -0,0 +1,14 @@
+
+
+
+ $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
+ true
+ A1B2C3D4-E5F6-4A5B-9C8D-7E6F5A4B3C2D
+
+
+ SharedProject
+
+
+
+
+
diff --git a/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/SharedProject/SharedProject.shproj b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/SharedProject/SharedProject.shproj
new file mode 100644
index 000000000000..3b86d62c4aa8
--- /dev/null
+++ b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/SharedProject/SharedProject.shproj
@@ -0,0 +1,13 @@
+
+
+
+ A1B2C3D4-E5F6-4A5B-9C8D-7E6F5A4B3C2D
+ 14.0
+
+
+
+
+
+
+
+
diff --git a/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/TestProject/Program.cs b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/TestProject/Program.cs
new file mode 100644
index 000000000000..e5bd6d0e05b0
--- /dev/null
+++ b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/TestProject/Program.cs
@@ -0,0 +1,66 @@
+using Microsoft.Testing.Platform.Builder;
+using Microsoft.Testing.Platform.Capabilities.TestFramework;
+using Microsoft.Testing.Platform.Extensions.Messages;
+using Microsoft.Testing.Platform.Extensions.TestFramework;
+
+for (int i = 0; i < 3; i++)
+{
+ Console.WriteLine(new string('a', 10000));
+ Console.Error.WriteLine(new string('e', 10000));
+}
+
+var testApplicationBuilder = await TestApplication.CreateBuilderAsync(args);
+
+testApplicationBuilder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_, __) => new DummyTestAdapter());
+
+using var testApplication = await testApplicationBuilder.BuildAsync();
+return await testApplication.RunAsync();
+
+public class DummyTestAdapter : ITestFramework, IDataProducer
+{
+ public string Uid => nameof(DummyTestAdapter);
+
+ public string Version => "2.0.0";
+
+ public string DisplayName => nameof(DummyTestAdapter);
+
+ public string Description => nameof(DummyTestAdapter);
+
+ public Task IsEnabledAsync() => Task.FromResult(true);
+
+ public Type[] DataTypesProduced => new[] {
+ typeof(TestNodeUpdateMessage)
+ };
+
+ public Task CreateTestSessionAsync(CreateTestSessionContext context)
+ => Task.FromResult(new CreateTestSessionResult() { IsSuccess = true });
+
+ public Task CloseTestSessionAsync(CloseTestSessionContext context)
+ => Task.FromResult(new CloseTestSessionResult() { IsSuccess = true });
+
+ public async Task ExecuteRequestAsync(ExecuteRequestContext context)
+ {
+ await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, new TestNode()
+ {
+ Uid = "Test0",
+ DisplayName = "Test0",
+ Properties = new PropertyBag(new PassedTestNodeStateProperty("OK")),
+ }));
+
+ await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, new TestNode()
+ {
+ Uid = "Test1",
+ DisplayName = "Test1",
+ Properties = new PropertyBag(new SkippedTestNodeStateProperty("OK skipped!")),
+ }));
+
+ await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, new TestNode()
+ {
+ Uid = "Test2",
+ DisplayName = "Test2",
+ Properties = new PropertyBag(new FailedTestNodeStateProperty(new Exception("this is a failed test"), "not OK")),
+ }));
+
+ context.Complete();
+ }
+}
\ No newline at end of file
diff --git a/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/TestProject/TestProject.csproj b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/TestProject/TestProject.csproj
new file mode 100644
index 000000000000..9857918867b1
--- /dev/null
+++ b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/TestProject/TestProject.csproj
@@ -0,0 +1,17 @@
+
+
+
+
+ $(CurrentTargetFramework)
+ Exe
+
+ enable
+ enable
+
+ false
+
+
+
+
+
+
diff --git a/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/TestProjectsWithShared.slnf b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/TestProjectsWithShared.slnf
new file mode 100644
index 000000000000..c964188ca085
--- /dev/null
+++ b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/TestProjectsWithShared.slnf
@@ -0,0 +1,9 @@
+{
+ "solution": {
+ "path": "MultiTestProjectSolutionWithSharedProject.slnx",
+ "projects": [
+ "TestProject/TestProject.csproj",
+ "SharedProject/SharedProject.shproj"
+ ]
+ }
+}
diff --git a/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/global.json b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/global.json
new file mode 100644
index 000000000000..9009caf0ba8f
--- /dev/null
+++ b/test/TestAssets/TestProjects/MultiTestProjectSolutionWithSharedProject/global.json
@@ -0,0 +1,5 @@
+{
+ "test": {
+ "runner": "Microsoft.Testing.Platform"
+ }
+}
diff --git a/test/dotnet.Tests/CommandTests/Test/GivenDotnetTestBuildsAndRunsTestsWithDifferentOptions.cs b/test/dotnet.Tests/CommandTests/Test/GivenDotnetTestBuildsAndRunsTestsWithDifferentOptions.cs
index 4559f8933439..13528fdbdd3c 100644
--- a/test/dotnet.Tests/CommandTests/Test/GivenDotnetTestBuildsAndRunsTestsWithDifferentOptions.cs
+++ b/test/dotnet.Tests/CommandTests/Test/GivenDotnetTestBuildsAndRunsTestsWithDifferentOptions.cs
@@ -566,5 +566,63 @@ public void RunWithTraceFileLoggingAndNonExistingDirectory_ShouldReturnExitCodeG
result.ExitCode.Should().Be(ExitCodes.AtLeastOneTestFailed);
}
+
+ [InlineData(TestingConstants.Debug)]
+ [InlineData(TestingConstants.Release)]
+ [Theory]
+ public void RunWithSolutionFilterContainingSharedProject_ShouldSkipSharedProjectAndSucceed(string configuration)
+ {
+ TestAsset testInstance = _testAssetsManager.CopyTestAsset("MultiTestProjectSolutionWithSharedProject", Guid.NewGuid().ToString()).WithSource();
+
+ string testSolutionFilterPath = "TestProjectsWithShared.slnf";
+
+ CommandResult result = new DotnetTestCommand(Log, disableNewOutput: false)
+ .WithWorkingDirectory(testInstance.Path)
+ .Execute(MicrosoftTestingPlatformOptions.SolutionOption.Name, testSolutionFilterPath,
+ MicrosoftTestingPlatformOptions.ConfigurationOption.Name, configuration);
+
+ // Validate that TestProject ran (shared project should be skipped automatically)
+ result.StdOut.Should().Contain("TestProject.dll");
+ // OtherTestProject should not be included since it's not in the solution filter
+ result.StdOut.Should().NotContain("OtherTestProject.dll");
+
+ result.ExitCode.Should().Be(ExitCodes.AtLeastOneTestFailed);
+ }
+
+ [InlineData(TestingConstants.Debug)]
+ [InlineData(TestingConstants.Release)]
+ [Theory]
+ public void RunWithSolutionAndPlatformConfiguration_ShouldRespectPlatform(string configuration)
+ {
+ TestAsset testInstance = _testAssetsManager.CopyTestAsset("MultiTestProjectSolutionWithPlatforms", Guid.NewGuid().ToString()).WithSource();
+
+ string testSolutionPath = "MultiTestProjectSolutionWithPlatforms.slnx";
+
+ // Test with x86 platform - OtherTestProject should NOT be included (no Build.0 for x86)
+ CommandResult resultX86 = new DotnetTestCommand(Log, disableNewOutput: false)
+ .WithWorkingDirectory(testInstance.Path)
+ .Execute(MicrosoftTestingPlatformOptions.SolutionOption.Name, testSolutionPath,
+ MicrosoftTestingPlatformOptions.ConfigurationOption.Name, configuration,
+ "--property:Platform=x86");
+
+ // Validate that TestProject ran but OtherTestProject did not (not marked for build on x86)
+ resultX86.StdOut.Should().Contain("TestProject.dll");
+ resultX86.StdOut.Should().NotContain("OtherTestProject.dll");
+
+ resultX86.ExitCode.Should().Be(ExitCodes.AtLeastOneTestFailed);
+
+ // Test with x64 platform - both projects should be included
+ CommandResult resultX64 = new DotnetTestCommand(Log, disableNewOutput: false)
+ .WithWorkingDirectory(testInstance.Path)
+ .Execute(MicrosoftTestingPlatformOptions.SolutionOption.Name, testSolutionPath,
+ MicrosoftTestingPlatformOptions.ConfigurationOption.Name, configuration,
+ "--property:Platform=x64");
+
+ // Validate that both TestProject and OtherTestProject ran
+ resultX64.StdOut.Should().Contain("TestProject.dll");
+ resultX64.StdOut.Should().Contain("OtherTestProject.dll");
+
+ resultX64.ExitCode.Should().Be(ExitCodes.AtLeastOneTestFailed);
+ }
}
}