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); + } } }