diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index be933b8df..3327d766b 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -32,6 +32,8 @@ + + diff --git a/src/Stryker.Abstractions/Options/IStrykerOptions.cs b/src/Stryker.Abstractions/Options/IStrykerOptions.cs index 7c7f21b66..0b518445d 100644 --- a/src/Stryker.Abstractions/Options/IStrykerOptions.cs +++ b/src/Stryker.Abstractions/Options/IStrykerOptions.cs @@ -46,6 +46,7 @@ public interface IStrykerOptions string TargetFramework { get; init; } string TestCaseFilter { get; init; } IEnumerable TestProjects { get; init; } + Testing.TestRunner TestRunner { get; init; } IThresholds Thresholds { get; init; } bool WithBaseline { get; init; } string WorkingDirectory { get; init; } diff --git a/src/Stryker.Abstractions/Testing/TestRunner.cs b/src/Stryker.Abstractions/Testing/TestRunner.cs new file mode 100644 index 000000000..60078270b --- /dev/null +++ b/src/Stryker.Abstractions/Testing/TestRunner.cs @@ -0,0 +1,19 @@ +namespace Stryker.Abstractions.Testing; + +/// +/// Specifies the test runner to use for running tests +/// +public enum TestRunner +{ + /// + /// Use Visual Studio Test Platform (VSTest). This is the default and currently the only fully supported option. + /// + VsTest = 0, + + /// + /// Use Microsoft Testing Platform (MTP). This is currently under development and not yet fully supported. + /// When specified, Stryker will attempt to use the new Microsoft Testing Platform for test execution. + /// Note: This option is experimental and may not work with all test frameworks or scenarios. + /// + MicrosoftTestingPlatform = 1 +} diff --git a/src/Stryker.CLI/Stryker.CLI.UnitTest/packages.lock.json b/src/Stryker.CLI/Stryker.CLI.UnitTest/packages.lock.json index edeecaf7e..f9221446e 100644 --- a/src/Stryker.CLI/Stryker.CLI.UnitTest/packages.lock.json +++ b/src/Stryker.CLI/Stryker.CLI.UnitTest/packages.lock.json @@ -285,15 +285,6 @@ "Microsoft.Testing.Platform": "1.9.0" } }, - "Microsoft.Testing.Extensions.TrxReport": { - "type": "Transitive", - "resolved": "1.9.0", - "contentHash": "/hcQOJ9Ktrz/nA90kUpN9mwZ4eWfiZLfO64Jq08Etf8YbidLtZFb3Xs/3v1amxAZ4nrTbQpmwr9X/aTs4LRBhQ==", - "dependencies": { - "Microsoft.Testing.Extensions.TrxReport.Abstractions": "1.9.0", - "Microsoft.Testing.Platform": "1.9.0" - } - }, "Microsoft.Testing.Extensions.TrxReport.Abstractions": { "type": "Transitive", "resolved": "1.9.0", @@ -314,11 +305,6 @@ "Microsoft.Testing.Platform": "1.9.0" } }, - "Microsoft.Testing.Platform": { - "type": "Transitive", - "resolved": "1.9.0", - "contentHash": "OE79Vc5rXwFYciAPY/mqv92XvdhK+pvCHdVHcS0bBpWwWQbnzI18FiSEEYY+lYpB0HHl0fDQgcCK3ZTYKGs8bA==" - }, "Microsoft.Testing.Platform.MSBuild": { "type": "Transitive", "resolved": "1.9.0", @@ -591,6 +577,11 @@ "resolved": "8.0.0", "contentHash": "ne1843evDugl0md7Fjzy6QjJrzsjh46ZKbhf8GwBXb5f/gw97J4bxMs0NQKifDuThh/f0bZ0e62NPl1jzTuRqA==" }, + "System.IO.Pipelines": { + "type": "Transitive", + "resolved": "9.0.9", + "contentHash": "VySjpsCLprojvat550Flrm3NQB982CPuDzILajqjQihFmrQXZPdQyktIbcpVPJyaExFYtAfY1DpwMdWQuS0kbw==" + }, "System.Management": { "type": "Transitive", "resolved": "6.0.1", @@ -813,13 +804,17 @@ }, "System.Text.Encodings.Web": { "type": "Transitive", - "resolved": "6.0.1", - "contentHash": "E5M5AE2OUTlCrf4omZvzzziUJO9CofBl+lXHaN5IKePPJvHqYFYYpaDPgCpR4VwaFbEebfnjOxxEBtPtsqAxpQ==" + "resolved": "9.0.9", + "contentHash": "bzYTmAcmfelUOCBxvbgsfSr2tq94ydA2gJZAxZRcuNa0LlmlVz8JNHst6RG1qsDujyVYT4vjv06y8sCLbvCXdg==" }, "System.Text.Json": { "type": "Transitive", - "resolved": "6.0.11", - "contentHash": "xqC1HIbJMBFhrpYs76oYP+NAskNVjc6v73HqLal7ECRDPIp4oRU5pPavkD//vNactCn9DA2aaald/I5N+uZ5/g==" + "resolved": "9.0.9", + "contentHash": "NEnpppwq67fRz/OvQRxsEMgetDJsxlxpEsAFO/4PZYbAyAMd4Ol6KS7phc8uDoKPsnbdzRLKobpX303uQwCqdg==", + "dependencies": { + "System.IO.Pipelines": "9.0.9", + "System.Text.Encodings.Web": "9.0.9" + } }, "System.Threading": { "type": "Transitive", @@ -898,13 +893,15 @@ "Serilog.Sinks.Console": "[6.0.0, )", "ShellProgressBar": "[5.2.0, )", "Spectre.Console": "[0.51.1, )", - "Stryker.Abstractions": "[4.8.1, )", - "Stryker.Configuration": "[4.8.1, )", - "Stryker.DataCollector": "[4.8.1, )", + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.Configuration": "[1.0.0, )", + "Stryker.DataCollector": "[1.0.0, )", "Stryker.Regex.Parser": "[1.0.0, )", - "Stryker.RegexMutators": "[4.8.1, )", - "Stryker.TestRunner.VsTest": "[4.8.1, )", - "Stryker.Utilities": "[4.8.1, )", + "Stryker.RegexMutators": "[1.0.0, )", + "Stryker.TestRunner": "[1.0.0, )", + "Stryker.TestRunner.MTP": "[1.0.0, )", + "Stryker.TestRunner.VsTest": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )", "TestableIO.System.IO.Abstractions.Wrappers": "[22.0.16, )" } }, @@ -927,8 +924,8 @@ "Microsoft.CodeAnalysis.CSharp": "[4.14.0, )", "Microsoft.CodeAnalysis.Common": "[4.14.0, )", "Serilog": "[4.3.0, )", - "Stryker.Abstractions": "[4.8.1, )", - "Stryker.Utilities": "[4.8.1, )" + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )" } }, "stryker.datacollector": { @@ -948,7 +945,20 @@ "type": "Project", "dependencies": { "Microsoft.TestPlatform.ObjectModel": "[17.14.1, )", - "Stryker.Abstractions": "[4.8.1, )" + "Stryker.Abstractions": "[1.0.0, )", + "TestableIO.System.IO.Abstractions.Wrappers": "[22.0.16, )" + } + }, + "stryker.testrunner.mtp": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "[9.0.9, )", + "Microsoft.Testing.Extensions.TrxReport": "[1.5.0, )", + "Microsoft.Testing.Platform": "[1.5.0, )", + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.TestRunner": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )", + "System.Net.Http.Json": "[9.0.9, )" } }, "stryker.testrunner.vstest": { @@ -959,10 +969,10 @@ "Microsoft.TestPlatform.ObjectModel": "[17.14.1, )", "Microsoft.TestPlatform.Portable": "[17.14.1, )", "Microsoft.TestPlatform.TranslationLayer": "[17.14.1, )", - "Stryker.Abstractions": "[4.8.1, )", - "Stryker.DataCollector": "[4.8.1, )", - "Stryker.TestRunner": "[4.8.1, )", - "Stryker.Utilities": "[4.8.1, )", + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.DataCollector": "[1.0.0, )", + "Stryker.TestRunner": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )", "TestableIO.System.IO.Abstractions.Wrappers": "[22.0.16, )" } }, @@ -975,7 +985,7 @@ "Microsoft.Extensions.Logging.Abstractions": "[9.0.9, )", "Mono.Cecil": "[0.11.6, )", "ResXResourceReader.NetStandard": "[1.3.0, )", - "Stryker.Abstractions": "[4.8.1, )" + "Stryker.Abstractions": "[1.0.0, )" } }, "Azure.Storage.Files.Shares": { @@ -1087,6 +1097,22 @@ "System.Diagnostics.DiagnosticSource": "9.0.9" } }, + "Microsoft.Testing.Extensions.TrxReport": { + "type": "CentralTransitive", + "requested": "[1.5.0, )", + "resolved": "1.9.0", + "contentHash": "/hcQOJ9Ktrz/nA90kUpN9mwZ4eWfiZLfO64Jq08Etf8YbidLtZFb3Xs/3v1amxAZ4nrTbQpmwr9X/aTs4LRBhQ==", + "dependencies": { + "Microsoft.Testing.Extensions.TrxReport.Abstractions": "1.9.0", + "Microsoft.Testing.Platform": "1.9.0" + } + }, + "Microsoft.Testing.Platform": { + "type": "CentralTransitive", + "requested": "[1.5.0, )", + "resolved": "1.9.0", + "contentHash": "OE79Vc5rXwFYciAPY/mqv92XvdhK+pvCHdVHcS0bBpWwWQbnzI18FiSEEYY+lYpB0HHl0fDQgcCK3ZTYKGs8bA==" + }, "Microsoft.TestPlatform": { "type": "CentralTransitive", "requested": "[17.14.1, )", @@ -1221,6 +1247,15 @@ "resolved": "1.0.0", "contentHash": "39OYYkvF2KlMbhxLBM+GTJEzPLu0HfN1v4AOApDFt3+ivd5F8HXwV5yp2A2+i7a7F5Tv2zr/7faCIqZj9c7x4g==" }, + "System.Net.Http.Json": { + "type": "CentralTransitive", + "requested": "[9.0.9, )", + "resolved": "9.0.9", + "contentHash": "Plss2+D6djmOMTkx/TbJ6vuz1bHjrhMXSj5DsjeWgK0PMRFPuc1Jo0TlFtgzbP3tMlG5U6Q+xB6ZwtMKRe1Ppw==", + "dependencies": { + "System.Text.Json": "9.0.9" + } + }, "TestableIO.System.IO.Abstractions.Wrappers": { "type": "CentralTransitive", "requested": "[22.0.16, )", diff --git a/src/Stryker.CLI/Stryker.CLI/packages.lock.json b/src/Stryker.CLI/Stryker.CLI/packages.lock.json index b3ba6da57..09522d3df 100644 --- a/src/Stryker.CLI/Stryker.CLI/packages.lock.json +++ b/src/Stryker.CLI/Stryker.CLI/packages.lock.json @@ -176,6 +176,14 @@ "resolved": "1.1.0", "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" }, + "Microsoft.Testing.Extensions.TrxReport.Abstractions": { + "type": "Transitive", + "resolved": "1.5.0", + "contentHash": "3vMXWbqqy3rSXYlPshR7CPqG0bgGDOhasyhVtqhAOy2tMED6VKU/IbKNMUmEuqgPNjMkCaicDTfNdXsrJPKcsw==", + "dependencies": { + "Microsoft.Testing.Platform": "1.5.0" + } + }, "MSBuild.StructuredLogger": { "type": "Transitive", "resolved": "2.2.158", @@ -399,6 +407,11 @@ "resolved": "8.0.0", "contentHash": "ne1843evDugl0md7Fjzy6QjJrzsjh46ZKbhf8GwBXb5f/gw97J4bxMs0NQKifDuThh/f0bZ0e62NPl1jzTuRqA==" }, + "System.IO.Pipelines": { + "type": "Transitive", + "resolved": "9.0.9", + "contentHash": "VySjpsCLprojvat550Flrm3NQB982CPuDzILajqjQihFmrQXZPdQyktIbcpVPJyaExFYtAfY1DpwMdWQuS0kbw==" + }, "System.Memory.Data": { "type": "Transitive", "resolved": "6.0.0", @@ -488,11 +501,6 @@ "Microsoft.NETCore.Targets": "1.1.0" } }, - "System.Runtime.CompilerServices.Unsafe": { - "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" - }, "System.Runtime.Extensions": { "type": "Transitive", "resolved": "4.1.0", @@ -608,19 +616,16 @@ }, "System.Text.Encodings.Web": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==", - "dependencies": { - "System.Runtime.CompilerServices.Unsafe": "6.0.0" - } + "resolved": "9.0.9", + "contentHash": "bzYTmAcmfelUOCBxvbgsfSr2tq94ydA2gJZAxZRcuNa0LlmlVz8JNHst6RG1qsDujyVYT4vjv06y8sCLbvCXdg==" }, "System.Text.Json": { "type": "Transitive", - "resolved": "6.0.10", - "contentHash": "NSB0kDipxn2ychp88NXWfFRFlmi1bst/xynOutbnpEfRCT9JZkZ7KOmF/I/hNKo2dILiMGnqblm+j1sggdLB9g==", + "resolved": "9.0.9", + "contentHash": "NEnpppwq67fRz/OvQRxsEMgetDJsxlxpEsAFO/4PZYbAyAMd4Ol6KS7phc8uDoKPsnbdzRLKobpX303uQwCqdg==", "dependencies": { - "System.Runtime.CompilerServices.Unsafe": "6.0.0", - "System.Text.Encodings.Web": "6.0.0" + "System.IO.Pipelines": "9.0.9", + "System.Text.Encodings.Web": "9.0.9" } }, "System.Threading": { @@ -691,13 +696,15 @@ "Serilog.Sinks.Console": "[6.0.0, )", "ShellProgressBar": "[5.2.0, )", "Spectre.Console": "[0.51.1, )", - "Stryker.Abstractions": "[4.8.1, )", - "Stryker.Configuration": "[4.8.1, )", - "Stryker.DataCollector": "[4.8.1, )", + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.Configuration": "[1.0.0, )", + "Stryker.DataCollector": "[1.0.0, )", "Stryker.Regex.Parser": "[1.0.0, )", - "Stryker.RegexMutators": "[4.8.1, )", - "Stryker.TestRunner.VsTest": "[4.8.1, )", - "Stryker.Utilities": "[4.8.1, )", + "Stryker.RegexMutators": "[1.0.0, )", + "Stryker.TestRunner": "[1.0.0, )", + "Stryker.TestRunner.MTP": "[1.0.0, )", + "Stryker.TestRunner.VsTest": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )", "TestableIO.System.IO.Abstractions.Wrappers": "[22.0.16, )" } }, @@ -720,8 +727,8 @@ "Microsoft.CodeAnalysis.CSharp": "[4.14.0, )", "Microsoft.CodeAnalysis.Common": "[4.14.0, )", "Serilog": "[4.3.0, )", - "Stryker.Abstractions": "[4.8.1, )", - "Stryker.Utilities": "[4.8.1, )" + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )" } }, "stryker.datacollector": { @@ -741,7 +748,20 @@ "type": "Project", "dependencies": { "Microsoft.TestPlatform.ObjectModel": "[17.14.1, )", - "Stryker.Abstractions": "[4.8.1, )" + "Stryker.Abstractions": "[1.0.0, )", + "TestableIO.System.IO.Abstractions.Wrappers": "[22.0.16, )" + } + }, + "stryker.testrunner.mtp": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "[9.0.9, )", + "Microsoft.Testing.Extensions.TrxReport": "[1.5.0, )", + "Microsoft.Testing.Platform": "[1.5.0, )", + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.TestRunner": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )", + "System.Net.Http.Json": "[9.0.9, )" } }, "stryker.testrunner.vstest": { @@ -752,10 +772,10 @@ "Microsoft.TestPlatform.ObjectModel": "[17.14.1, )", "Microsoft.TestPlatform.Portable": "[17.14.1, )", "Microsoft.TestPlatform.TranslationLayer": "[17.14.1, )", - "Stryker.Abstractions": "[4.8.1, )", - "Stryker.DataCollector": "[4.8.1, )", - "Stryker.TestRunner": "[4.8.1, )", - "Stryker.Utilities": "[4.8.1, )", + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.DataCollector": "[1.0.0, )", + "Stryker.TestRunner": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )", "TestableIO.System.IO.Abstractions.Wrappers": "[22.0.16, )" } }, @@ -768,7 +788,7 @@ "Microsoft.Extensions.Logging.Abstractions": "[9.0.9, )", "Mono.Cecil": "[0.11.6, )", "ResXResourceReader.NetStandard": "[1.3.0, )", - "Stryker.Abstractions": "[4.8.1, )" + "Stryker.Abstractions": "[1.0.0, )" } }, "Azure.Storage.Files.Shares": { @@ -871,6 +891,22 @@ "System.Diagnostics.DiagnosticSource": "9.0.9" } }, + "Microsoft.Testing.Extensions.TrxReport": { + "type": "CentralTransitive", + "requested": "[1.5.0, )", + "resolved": "1.5.0", + "contentHash": "+AW10NEScLAiErRKzek5U1Kv0B337EktcLt6ruzJXFTbtdQgK+3j0jxWbnfSs1N+R1eX2AsNF9/en7hWW8DDfg==", + "dependencies": { + "Microsoft.Testing.Extensions.TrxReport.Abstractions": "1.5.0", + "Microsoft.Testing.Platform": "1.5.0" + } + }, + "Microsoft.Testing.Platform": { + "type": "CentralTransitive", + "requested": "[1.5.0, )", + "resolved": "1.5.0", + "contentHash": "L6MsgthfCEuqx4Z3VWmUzilFN4I4hrRIXY0UgGTP9sv9upt1V9m5x9m7fWUKRrnzoE8yTFeRxw1KaI9XmXIzRA==" + }, "Microsoft.TestPlatform": { "type": "CentralTransitive", "requested": "[17.14.1, )", @@ -987,6 +1023,15 @@ "resolved": "1.0.0", "contentHash": "39OYYkvF2KlMbhxLBM+GTJEzPLu0HfN1v4AOApDFt3+ivd5F8HXwV5yp2A2+i7a7F5Tv2zr/7faCIqZj9c7x4g==" }, + "System.Net.Http.Json": { + "type": "CentralTransitive", + "requested": "[9.0.9, )", + "resolved": "9.0.9", + "contentHash": "Plss2+D6djmOMTkx/TbJ6vuz1bHjrhMXSj5DsjeWgK0PMRFPuc1Jo0TlFtgzbP3tMlG5U6Q+xB6ZwtMKRe1Ppw==", + "dependencies": { + "System.Text.Json": "9.0.9" + } + }, "TestableIO.System.IO.Abstractions.Wrappers": { "type": "CentralTransitive", "requested": "[22.0.16, )", diff --git a/src/Stryker.Core/Stryker.Core.UnitTest/TestRunner/TestRunnerFactoryTests.cs b/src/Stryker.Core/Stryker.Core.UnitTest/TestRunner/TestRunnerFactoryTests.cs new file mode 100644 index 000000000..67b7a8925 --- /dev/null +++ b/src/Stryker.Core/Stryker.Core.UnitTest/TestRunner/TestRunnerFactoryTests.cs @@ -0,0 +1,59 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Shouldly; +using Stryker.Abstractions; +using Stryker.Abstractions.Options; +using Stryker.Abstractions.Testing; +using Stryker.TestRunner; + +namespace Stryker.Core.UnitTest.TestRunner; + +[TestClass] +public class TestRunnerFactoryTests : TestBase +{ + [TestMethod] + public void ShouldCreateVsTestRunnerByDefault() + { + var options = new StrykerOptions + { + ProjectPath = "/test", + TestRunner = Abstractions.Testing.TestRunner.VsTest + }; + + var runner = TestRunnerFactory.Create(options); + + runner.ShouldNotBeNull(); + runner.GetType().Name.ShouldBe("VsTestRunnerPool"); + } + + [TestMethod] + public void ShouldCreateMtpRunner() + { + var options = new StrykerOptions + { + ProjectPath = "/test", + TestRunner = Abstractions.Testing.TestRunner.MicrosoftTestingPlatform + }; + + var runner = TestRunnerFactory.Create(options); + + runner.ShouldNotBeNull(); + runner.GetType().Name.ShouldBe("MicrosoftTestingPlatformRunner"); + } + + [TestMethod] + public void ShouldDefaultToVsTestWhenOptionNotSpecified() + { + // When TestRunner is not explicitly set, it should default to VsTest + var options = new StrykerOptions + { + ProjectPath = "/test" + // TestRunner not set, should use default + }; + + var runner = TestRunnerFactory.Create(options); + + runner.ShouldNotBeNull(); + runner.GetType().Name.ShouldBe("VsTestRunnerPool"); + } +} diff --git a/src/Stryker.Core/Stryker.Core.UnitTest/packages.lock.json b/src/Stryker.Core/Stryker.Core.UnitTest/packages.lock.json index bacbd1530..4a4095506 100644 --- a/src/Stryker.Core/Stryker.Core.UnitTest/packages.lock.json +++ b/src/Stryker.Core/Stryker.Core.UnitTest/packages.lock.json @@ -320,15 +320,6 @@ "Microsoft.Testing.Platform": "1.9.0" } }, - "Microsoft.Testing.Extensions.TrxReport": { - "type": "Transitive", - "resolved": "1.9.0", - "contentHash": "/hcQOJ9Ktrz/nA90kUpN9mwZ4eWfiZLfO64Jq08Etf8YbidLtZFb3Xs/3v1amxAZ4nrTbQpmwr9X/aTs4LRBhQ==", - "dependencies": { - "Microsoft.Testing.Extensions.TrxReport.Abstractions": "1.9.0", - "Microsoft.Testing.Platform": "1.9.0" - } - }, "Microsoft.Testing.Extensions.TrxReport.Abstractions": { "type": "Transitive", "resolved": "1.9.0", @@ -349,11 +340,6 @@ "Microsoft.Testing.Platform": "1.9.0" } }, - "Microsoft.Testing.Platform": { - "type": "Transitive", - "resolved": "1.9.0", - "contentHash": "OE79Vc5rXwFYciAPY/mqv92XvdhK+pvCHdVHcS0bBpWwWQbnzI18FiSEEYY+lYpB0HHl0fDQgcCK3ZTYKGs8bA==" - }, "Microsoft.Testing.Platform.MSBuild": { "type": "Transitive", "resolved": "1.9.0", @@ -587,6 +573,11 @@ "resolved": "8.0.0", "contentHash": "ne1843evDugl0md7Fjzy6QjJrzsjh46ZKbhf8GwBXb5f/gw97J4bxMs0NQKifDuThh/f0bZ0e62NPl1jzTuRqA==" }, + "System.IO.Pipelines": { + "type": "Transitive", + "resolved": "9.0.9", + "contentHash": "VySjpsCLprojvat550Flrm3NQB982CPuDzILajqjQihFmrQXZPdQyktIbcpVPJyaExFYtAfY1DpwMdWQuS0kbw==" + }, "System.Management": { "type": "Transitive", "resolved": "6.0.1", @@ -809,13 +800,17 @@ }, "System.Text.Encodings.Web": { "type": "Transitive", - "resolved": "6.0.1", - "contentHash": "E5M5AE2OUTlCrf4omZvzzziUJO9CofBl+lXHaN5IKePPJvHqYFYYpaDPgCpR4VwaFbEebfnjOxxEBtPtsqAxpQ==" + "resolved": "9.0.9", + "contentHash": "bzYTmAcmfelUOCBxvbgsfSr2tq94ydA2gJZAxZRcuNa0LlmlVz8JNHst6RG1qsDujyVYT4vjv06y8sCLbvCXdg==" }, "System.Text.Json": { "type": "Transitive", - "resolved": "6.0.11", - "contentHash": "xqC1HIbJMBFhrpYs76oYP+NAskNVjc6v73HqLal7ECRDPIp4oRU5pPavkD//vNactCn9DA2aaald/I5N+uZ5/g==" + "resolved": "9.0.9", + "contentHash": "NEnpppwq67fRz/OvQRxsEMgetDJsxlxpEsAFO/4PZYbAyAMd4Ol6KS7phc8uDoKPsnbdzRLKobpX303uQwCqdg==", + "dependencies": { + "System.IO.Pipelines": "9.0.9", + "System.Text.Encodings.Web": "9.0.9" + } }, "System.Threading": { "type": "Transitive", @@ -885,13 +880,15 @@ "Serilog.Sinks.Console": "[6.0.0, )", "ShellProgressBar": "[5.2.0, )", "Spectre.Console": "[0.51.1, )", - "Stryker.Abstractions": "[4.8.1, )", - "Stryker.Configuration": "[4.8.1, )", - "Stryker.DataCollector": "[4.8.1, )", + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.Configuration": "[1.0.0, )", + "Stryker.DataCollector": "[1.0.0, )", "Stryker.Regex.Parser": "[1.0.0, )", - "Stryker.RegexMutators": "[4.8.1, )", - "Stryker.TestRunner.VsTest": "[4.8.1, )", - "Stryker.Utilities": "[4.8.1, )", + "Stryker.RegexMutators": "[1.0.0, )", + "Stryker.TestRunner": "[1.0.0, )", + "Stryker.TestRunner.MTP": "[1.0.0, )", + "Stryker.TestRunner.VsTest": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )", "TestableIO.System.IO.Abstractions.Wrappers": "[22.0.16, )" } }, @@ -914,8 +911,8 @@ "Microsoft.CodeAnalysis.CSharp": "[4.14.0, )", "Microsoft.CodeAnalysis.Common": "[4.14.0, )", "Serilog": "[4.3.0, )", - "Stryker.Abstractions": "[4.8.1, )", - "Stryker.Utilities": "[4.8.1, )" + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )" } }, "stryker.datacollector": { @@ -935,7 +932,20 @@ "type": "Project", "dependencies": { "Microsoft.TestPlatform.ObjectModel": "[17.14.1, )", - "Stryker.Abstractions": "[4.8.1, )" + "Stryker.Abstractions": "[1.0.0, )", + "TestableIO.System.IO.Abstractions.Wrappers": "[22.0.16, )" + } + }, + "stryker.testrunner.mtp": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "[9.0.9, )", + "Microsoft.Testing.Extensions.TrxReport": "[1.5.0, )", + "Microsoft.Testing.Platform": "[1.5.0, )", + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.TestRunner": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )", + "System.Net.Http.Json": "[9.0.9, )" } }, "stryker.testrunner.vstest": { @@ -946,10 +956,10 @@ "Microsoft.TestPlatform.ObjectModel": "[17.14.1, )", "Microsoft.TestPlatform.Portable": "[17.14.1, )", "Microsoft.TestPlatform.TranslationLayer": "[17.14.1, )", - "Stryker.Abstractions": "[4.8.1, )", - "Stryker.DataCollector": "[4.8.1, )", - "Stryker.TestRunner": "[4.8.1, )", - "Stryker.Utilities": "[4.8.1, )", + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.DataCollector": "[1.0.0, )", + "Stryker.TestRunner": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )", "TestableIO.System.IO.Abstractions.Wrappers": "[22.0.16, )" } }, @@ -962,7 +972,7 @@ "Microsoft.Extensions.Logging.Abstractions": "[9.0.9, )", "Mono.Cecil": "[0.11.6, )", "ResXResourceReader.NetStandard": "[1.3.0, )", - "Stryker.Abstractions": "[4.8.1, )" + "Stryker.Abstractions": "[1.0.0, )" } }, "Azure.Storage.Files.Shares": { @@ -1062,6 +1072,22 @@ "System.Diagnostics.DiagnosticSource": "9.0.9" } }, + "Microsoft.Testing.Extensions.TrxReport": { + "type": "CentralTransitive", + "requested": "[1.5.0, )", + "resolved": "1.9.0", + "contentHash": "/hcQOJ9Ktrz/nA90kUpN9mwZ4eWfiZLfO64Jq08Etf8YbidLtZFb3Xs/3v1amxAZ4nrTbQpmwr9X/aTs4LRBhQ==", + "dependencies": { + "Microsoft.Testing.Extensions.TrxReport.Abstractions": "1.9.0", + "Microsoft.Testing.Platform": "1.9.0" + } + }, + "Microsoft.Testing.Platform": { + "type": "CentralTransitive", + "requested": "[1.5.0, )", + "resolved": "1.9.0", + "contentHash": "OE79Vc5rXwFYciAPY/mqv92XvdhK+pvCHdVHcS0bBpWwWQbnzI18FiSEEYY+lYpB0HHl0fDQgcCK3ZTYKGs8bA==" + }, "Microsoft.TestPlatform": { "type": "CentralTransitive", "requested": "[17.14.1, )", @@ -1181,6 +1207,15 @@ "resolved": "0.51.1", "contentHash": "84xNywgnaG8XgOypnZAL+EZUbhCGE0umj7fuMrSI6esdE74HYHRoeBioeMUJXPiCt7iBDKHLwiBcg0IliYIIxA==" }, + "System.Net.Http.Json": { + "type": "CentralTransitive", + "requested": "[9.0.9, )", + "resolved": "9.0.9", + "contentHash": "Plss2+D6djmOMTkx/TbJ6vuz1bHjrhMXSj5DsjeWgK0PMRFPuc1Jo0TlFtgzbP3tMlG5U6Q+xB6ZwtMKRe1Ppw==", + "dependencies": { + "System.Text.Json": "9.0.9" + } + }, "TestableIO.System.IO.Abstractions.Wrappers": { "type": "CentralTransitive", "requested": "[22.0.16, )", diff --git a/src/Stryker.Core/Stryker.Core/Initialisation/ProjectOrchestrator.cs b/src/Stryker.Core/Stryker.Core/Initialisation/ProjectOrchestrator.cs index 7146e7a38..8c7b63e81 100644 --- a/src/Stryker.Core/Stryker.Core/Initialisation/ProjectOrchestrator.cs +++ b/src/Stryker.Core/Stryker.Core/Initialisation/ProjectOrchestrator.cs @@ -13,7 +13,7 @@ using Stryker.Abstractions.Testing; using Stryker.Core.MutationTest; using Stryker.Core.ProjectComponents.SourceProjects; -using Stryker.TestRunner.VsTest; +using Stryker.TestRunner; using Stryker.Utilities.Logging; namespace Stryker.Core.Initialisation; @@ -59,8 +59,8 @@ public IEnumerable MutateProjects(IStrykerOptions options, _initializationProcess.BuildProjects(options, projectInfos); - // create a test runner - _runner = runner ?? new VsTestRunnerPool(options, fileSystem: _fileResolver.FileSystem); + // create a test runner using the factory + _runner = runner ?? TestRunnerFactory.Create(options, _fileResolver.FileSystem); InitializeDashboardProjectInformation(options, projectInfos.First()); var inputs = _initializationProcess.GetMutationTestInputs(options, projectInfos, _runner); diff --git a/src/Stryker.Core/Stryker.Core/Stryker.Core.csproj b/src/Stryker.Core/Stryker.Core/Stryker.Core.csproj index 237360bd3..b92d4a5ff 100644 --- a/src/Stryker.Core/Stryker.Core/Stryker.Core.csproj +++ b/src/Stryker.Core/Stryker.Core/Stryker.Core.csproj @@ -95,7 +95,9 @@ + + diff --git a/src/Stryker.Core/Stryker.Core/packages.lock.json b/src/Stryker.Core/Stryker.Core/packages.lock.json index cfc10282e..fe63f4118 100644 --- a/src/Stryker.Core/Stryker.Core/packages.lock.json +++ b/src/Stryker.Core/Stryker.Core/packages.lock.json @@ -364,6 +364,14 @@ "resolved": "1.1.0", "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" }, + "Microsoft.Testing.Extensions.TrxReport.Abstractions": { + "type": "Transitive", + "resolved": "1.5.0", + "contentHash": "3vMXWbqqy3rSXYlPshR7CPqG0bgGDOhasyhVtqhAOy2tMED6VKU/IbKNMUmEuqgPNjMkCaicDTfNdXsrJPKcsw==", + "dependencies": { + "Microsoft.Testing.Platform": "1.5.0" + } + }, "MSBuild.StructuredLogger": { "type": "Transitive", "resolved": "2.2.158", @@ -543,6 +551,11 @@ "resolved": "8.0.0", "contentHash": "ne1843evDugl0md7Fjzy6QjJrzsjh46ZKbhf8GwBXb5f/gw97J4bxMs0NQKifDuThh/f0bZ0e62NPl1jzTuRqA==" }, + "System.IO.Pipelines": { + "type": "Transitive", + "resolved": "9.0.9", + "contentHash": "VySjpsCLprojvat550Flrm3NQB982CPuDzILajqjQihFmrQXZPdQyktIbcpVPJyaExFYtAfY1DpwMdWQuS0kbw==" + }, "System.Memory.Data": { "type": "Transitive", "resolved": "6.0.0", @@ -632,11 +645,6 @@ "Microsoft.NETCore.Targets": "1.1.0" } }, - "System.Runtime.CompilerServices.Unsafe": { - "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" - }, "System.Runtime.Extensions": { "type": "Transitive", "resolved": "4.1.0", @@ -752,19 +760,16 @@ }, "System.Text.Encodings.Web": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==", - "dependencies": { - "System.Runtime.CompilerServices.Unsafe": "6.0.0" - } + "resolved": "9.0.9", + "contentHash": "bzYTmAcmfelUOCBxvbgsfSr2tq94ydA2gJZAxZRcuNa0LlmlVz8JNHst6RG1qsDujyVYT4vjv06y8sCLbvCXdg==" }, "System.Text.Json": { "type": "Transitive", - "resolved": "6.0.10", - "contentHash": "NSB0kDipxn2ychp88NXWfFRFlmi1bst/xynOutbnpEfRCT9JZkZ7KOmF/I/hNKo2dILiMGnqblm+j1sggdLB9g==", + "resolved": "9.0.9", + "contentHash": "NEnpppwq67fRz/OvQRxsEMgetDJsxlxpEsAFO/4PZYbAyAMd4Ol6KS7phc8uDoKPsnbdzRLKobpX303uQwCqdg==", "dependencies": { - "System.Runtime.CompilerServices.Unsafe": "6.0.0", - "System.Text.Encodings.Web": "6.0.0" + "System.IO.Pipelines": "9.0.9", + "System.Text.Encodings.Web": "9.0.9" } }, "System.Threading": { @@ -830,8 +835,8 @@ "Microsoft.CodeAnalysis.CSharp": "[4.14.0, )", "Microsoft.CodeAnalysis.Common": "[4.14.0, )", "Serilog": "[4.3.0, )", - "Stryker.Abstractions": "[4.8.1, )", - "Stryker.Utilities": "[4.8.1, )" + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )" } }, "stryker.datacollector": { @@ -851,7 +856,20 @@ "type": "Project", "dependencies": { "Microsoft.TestPlatform.ObjectModel": "[17.14.1, )", - "Stryker.Abstractions": "[4.8.1, )" + "Stryker.Abstractions": "[1.0.0, )", + "TestableIO.System.IO.Abstractions.Wrappers": "[22.0.16, )" + } + }, + "stryker.testrunner.mtp": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "[9.0.9, )", + "Microsoft.Testing.Extensions.TrxReport": "[1.5.0, )", + "Microsoft.Testing.Platform": "[1.5.0, )", + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.TestRunner": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )", + "System.Net.Http.Json": "[9.0.9, )" } }, "stryker.testrunner.vstest": { @@ -862,10 +880,10 @@ "Microsoft.TestPlatform.ObjectModel": "[17.14.1, )", "Microsoft.TestPlatform.Portable": "[17.14.1, )", "Microsoft.TestPlatform.TranslationLayer": "[17.14.1, )", - "Stryker.Abstractions": "[4.8.1, )", - "Stryker.DataCollector": "[4.8.1, )", - "Stryker.TestRunner": "[4.8.1, )", - "Stryker.Utilities": "[4.8.1, )", + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.DataCollector": "[1.0.0, )", + "Stryker.TestRunner": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )", "TestableIO.System.IO.Abstractions.Wrappers": "[22.0.16, )" } }, @@ -878,7 +896,7 @@ "Microsoft.Extensions.Logging.Abstractions": "[9.0.9, )", "Mono.Cecil": "[0.11.6, )", "ResXResourceReader.NetStandard": "[1.3.0, )", - "Stryker.Abstractions": "[4.8.1, )" + "Stryker.Abstractions": "[1.0.0, )" } }, "Microsoft.CodeAnalysis.VisualBasic": { @@ -900,11 +918,36 @@ "System.Diagnostics.DiagnosticSource": "9.0.9" } }, + "Microsoft.Testing.Extensions.TrxReport": { + "type": "CentralTransitive", + "requested": "[1.5.0, )", + "resolved": "1.5.0", + "contentHash": "+AW10NEScLAiErRKzek5U1Kv0B337EktcLt6ruzJXFTbtdQgK+3j0jxWbnfSs1N+R1eX2AsNF9/en7hWW8DDfg==", + "dependencies": { + "Microsoft.Testing.Extensions.TrxReport.Abstractions": "1.5.0", + "Microsoft.Testing.Platform": "1.5.0" + } + }, + "Microsoft.Testing.Platform": { + "type": "CentralTransitive", + "requested": "[1.5.0, )", + "resolved": "1.5.0", + "contentHash": "L6MsgthfCEuqx4Z3VWmUzilFN4I4hrRIXY0UgGTP9sv9upt1V9m5x9m7fWUKRrnzoE8yTFeRxw1KaI9XmXIzRA==" + }, "ResXResourceReader.NetStandard": { "type": "CentralTransitive", "requested": "[1.3.0, )", "resolved": "1.3.0", "contentHash": "voW0VHwFGIvbJ4Pp/wfHKFGn9kxZD97H/mnD6LziBJCi4FJZtetYQpQQnpYp0IkL2+PQ6VOzkMvhK1+s7+NJnA==" + }, + "System.Net.Http.Json": { + "type": "CentralTransitive", + "requested": "[9.0.9, )", + "resolved": "9.0.9", + "contentHash": "Plss2+D6djmOMTkx/TbJ6vuz1bHjrhMXSj5DsjeWgK0PMRFPuc1Jo0TlFtgzbP3tMlG5U6Q+xB6ZwtMKRe1Ppw==", + "dependencies": { + "System.Text.Json": "9.0.9" + } } } } diff --git a/src/Stryker.Options/Options/Inputs/TestRunnerInput.cs b/src/Stryker.Options/Options/Inputs/TestRunnerInput.cs new file mode 100644 index 000000000..0896629df --- /dev/null +++ b/src/Stryker.Options/Options/Inputs/TestRunnerInput.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using Stryker.Abstractions.Exceptions; +using Stryker.Abstractions.Testing; + +namespace Stryker.Abstractions.Options.Inputs; + +public class TestRunnerInput : Input +{ + public override string Default => Testing.TestRunner.VsTest.ToString(); + + protected override string Description => "Specify which test runner to use for running tests. VsTest is the default and currently the only fully supported option."; + protected override IEnumerable AllowedOptions => EnumToStrings(typeof(Testing.TestRunner)); + + public Testing.TestRunner Validate() + { + if (SuppliedInput is null) + { + return Testing.TestRunner.VsTest; + } + else if (Enum.TryParse(SuppliedInput, true, out Testing.TestRunner runner)) + { + return runner; + } + else + { + throw new InputException($"The given test runner ({SuppliedInput}) is invalid. Valid options are: [{string.Join(", ", ((IEnumerable)Enum.GetValues(typeof(Testing.TestRunner))))}]"); + } + } +} diff --git a/src/Stryker.Options/Options/StrykerInputs.cs b/src/Stryker.Options/Options/StrykerInputs.cs index 7066940d1..d2a18eb90 100644 --- a/src/Stryker.Options/Options/StrykerInputs.cs +++ b/src/Stryker.Options/Options/StrykerInputs.cs @@ -41,6 +41,7 @@ public interface IStrykerInputs TargetFrameworkInput TargetFrameworkInput { get; init; } TestProjectsInput TestProjectsInput { get; init; } TestCaseFilterInput TestCaseFilterInput { get; init; } + TestRunnerInput TestRunnerInput { get; init; } ThresholdBreakInput ThresholdBreakInput { get; init; } ThresholdHighInput ThresholdHighInput { get; init; } ThresholdLowInput ThresholdLowInput { get; init; } @@ -82,6 +83,7 @@ public StrykerInputs(IFileSystem fileSystem = null) public SourceProjectNameInput SourceProjectNameInput { get; init; } = new(); public TestProjectsInput TestProjectsInput { get; init; } = new(); public TestCaseFilterInput TestCaseFilterInput { get; init; } = new(); + public TestRunnerInput TestRunnerInput { get; init; } = new(); public WithBaselineInput WithBaselineInput { get; init; } = new(); public ReportersInput ReportersInput { get; init; } = new(); public BaselineProviderInput BaselineProviderInput { get; init; } = new(); @@ -153,6 +155,7 @@ public IStrykerOptions ValidateAll() OptimizationMode = CoverageAnalysisInput.Validate() | DisableBailInput.Validate() | DisableMixMutantsInput.Validate(), TestProjects = TestProjectsInput.Validate(), TestCaseFilter = TestCaseFilterInput.Validate(), + TestRunner = TestRunnerInput.Validate(), DashboardUrl = DashboardUrlInput.Validate(), DashboardApiKey = DashboardApiKeyInput.Validate(withBaseline, baselineProvider, reporters), ProjectName = ProjectNameInput.Validate(), diff --git a/src/Stryker.Options/Options/StrykerOptions.cs b/src/Stryker.Options/Options/StrykerOptions.cs index 9ac02f647..3f494bd5f 100644 --- a/src/Stryker.Options/Options/StrykerOptions.cs +++ b/src/Stryker.Options/Options/StrykerOptions.cs @@ -6,6 +6,7 @@ using Stryker.Abstractions.Baseline; using Stryker.Abstractions.Options; using Stryker.Abstractions.ProjectComponents; +using Stryker.Abstractions.Testing; using Stryker.Utilities; namespace Stryker.Abstractions; @@ -116,6 +117,11 @@ public class StrykerOptions : IStrykerOptions /// public string TestCaseFilter { get; init; } + /// + /// The test runner to use for running tests. Defaults to VsTest. + /// + public Testing.TestRunner TestRunner { get; init; } = Testing.TestRunner.VsTest; + /// /// The reports that should be activated when stryker is done testing. /// diff --git a/src/Stryker.RegexMutators/Stryker.RegexMutators.UnitTest/packages.lock.json b/src/Stryker.RegexMutators/Stryker.RegexMutators.UnitTest/packages.lock.json index ff1685d6c..7181e0d26 100644 --- a/src/Stryker.RegexMutators/Stryker.RegexMutators.UnitTest/packages.lock.json +++ b/src/Stryker.RegexMutators/Stryker.RegexMutators.UnitTest/packages.lock.json @@ -104,15 +104,6 @@ "Microsoft.Testing.Platform": "1.9.0" } }, - "Microsoft.Testing.Extensions.TrxReport": { - "type": "Transitive", - "resolved": "1.9.0", - "contentHash": "/hcQOJ9Ktrz/nA90kUpN9mwZ4eWfiZLfO64Jq08Etf8YbidLtZFb3Xs/3v1amxAZ4nrTbQpmwr9X/aTs4LRBhQ==", - "dependencies": { - "Microsoft.Testing.Extensions.TrxReport.Abstractions": "1.9.0", - "Microsoft.Testing.Platform": "1.9.0" - } - }, "Microsoft.Testing.Extensions.TrxReport.Abstractions": { "type": "Transitive", "resolved": "1.9.0", @@ -133,11 +124,6 @@ "Microsoft.Testing.Platform": "1.9.0" } }, - "Microsoft.Testing.Platform": { - "type": "Transitive", - "resolved": "1.9.0", - "contentHash": "OE79Vc5rXwFYciAPY/mqv92XvdhK+pvCHdVHcS0bBpWwWQbnzI18FiSEEYY+lYpB0HHl0fDQgcCK3ZTYKGs8bA==" - }, "Microsoft.Testing.Platform.MSBuild": { "type": "Transitive", "resolved": "1.9.0", @@ -241,6 +227,22 @@ "Stryker.Regex.Parser": "[1.0.0, )" } }, + "Microsoft.Testing.Extensions.TrxReport": { + "type": "CentralTransitive", + "requested": "[1.5.0, )", + "resolved": "1.9.0", + "contentHash": "/hcQOJ9Ktrz/nA90kUpN9mwZ4eWfiZLfO64Jq08Etf8YbidLtZFb3Xs/3v1amxAZ4nrTbQpmwr9X/aTs4LRBhQ==", + "dependencies": { + "Microsoft.Testing.Extensions.TrxReport.Abstractions": "1.9.0", + "Microsoft.Testing.Platform": "1.9.0" + } + }, + "Microsoft.Testing.Platform": { + "type": "CentralTransitive", + "requested": "[1.5.0, )", + "resolved": "1.9.0", + "contentHash": "OE79Vc5rXwFYciAPY/mqv92XvdhK+pvCHdVHcS0bBpWwWQbnzI18FiSEEYY+lYpB0HHl0fDQgcCK3ZTYKGs8bA==" + }, "Microsoft.TestPlatform.ObjectModel": { "type": "CentralTransitive", "requested": "[17.14.1, )", diff --git a/src/Stryker.TestRunner.MTP/MicrosoftTestingPlatformRunner.cs b/src/Stryker.TestRunner.MTP/MicrosoftTestingPlatformRunner.cs new file mode 100644 index 000000000..fc0902d59 --- /dev/null +++ b/src/Stryker.TestRunner.MTP/MicrosoftTestingPlatformRunner.cs @@ -0,0 +1,431 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Stryker.Abstractions; +using Stryker.Abstractions.Options; +using Stryker.Abstractions.Testing; +using Stryker.TestRunner.Results; +using Stryker.TestRunner.Tests; +using Stryker.Utilities.Logging; + +namespace Stryker.TestRunner.MTP; + +/// +/// Microsoft Testing Platform runner implementation. +/// Basic implementation that runs tests using dotnet test with MTP-enabled test projects. +/// +public class MicrosoftTestingPlatformRunner : ITestRunner +{ + private readonly ILogger _logger; + private readonly IStrykerOptions _options; + private readonly Dictionary _discoveredTests = new(); + private readonly Dictionary> _testsPerAssembly = new(); + + public MicrosoftTestingPlatformRunner(IStrykerOptions options) + { + _options = options ?? throw new ArgumentNullException(nameof(options)); + _logger = ApplicationLogging.LoggerFactory.CreateLogger(); + _logger.LogInformation("Microsoft Testing Platform runner initialized. This is an experimental feature."); + } + + public bool DiscoverTests(string assembly) + { + try + { + _logger.LogInformation("Discovering tests in assembly: {Assembly}", assembly); + + if (!File.Exists(assembly)) + { + _logger.LogWarning("Assembly not found: {Assembly}", assembly); + return false; + } + + // Run dotnet test with list-tests to discover tests + var result = RunDotnetTest(assembly, "--list-tests", timeout: 30000); + + if (result.ExitCode != 0) + { + _logger.LogWarning("Test discovery failed for {Assembly} with exit code {ExitCode}", assembly, result.ExitCode); + return false; + } + + // Parse the output to extract test names + var testNames = ParseListTestsOutput(result.Output); + + _testsPerAssembly[assembly] = new HashSet(); + + foreach (var testName in testNames) + { + var testId = Guid.NewGuid().ToString(); + var testDesc = new MtpTestDescription(testId, testName, assembly); + _discoveredTests[testId] = testDesc; + _testsPerAssembly[assembly].Add(testId); + } + + _logger.LogInformation("Discovered {Count} tests in {Assembly}", testNames.Count, assembly); + return testNames.Count > 0; + } + catch (Exception ex) + { + _logger.LogError(ex, "Error discovering tests in {Assembly}", assembly); + return false; + } + } + + public ITestSet GetTests(IProjectAndTests project) + { + var testIds = new List(); + + foreach (var assembly in project.GetTestAssemblies()) + { + if (_testsPerAssembly.TryGetValue(assembly, out var tests)) + { + testIds.AddRange(tests); + } + } + + return new MtpTestSet(_discoveredTests.Where(t => testIds.Contains(t.Key)).Select(t => t.Value)); + } + + public ITestRunResult InitialTest(IProjectAndTests project) + { + _logger.LogInformation("Running initial test for project"); + + try + { + var startTime = DateTime.UtcNow; + var allTests = GetTests(project); + var failedTests = new List(); + var executedTests = new List(); + var allMessages = new List(); + + foreach (var assembly in project.GetTestAssemblies()) + { + if (!_testsPerAssembly.ContainsKey(assembly)) + { + _logger.LogWarning("No tests discovered for assembly: {Assembly}", assembly); + continue; + } + + // Run all tests in the assembly + var result = RunDotnetTest(assembly, "", timeout: _options.AdditionalTimeout + 60000); + allMessages.Add(result.Output); + + var assemblyTestIds = _testsPerAssembly[assembly]; + executedTests.AddRange(assemblyTestIds); + + if (result.ExitCode != 0) + { + // Parse output to determine which tests failed + var failedTestNames = ParseFailedTests(result.Output); + foreach (var failedName in failedTestNames) + { + var failedTest = _discoveredTests.Values.FirstOrDefault(t => t.Name == failedName && assemblyTestIds.Contains(t.Id)); + if (failedTest != null) + { + failedTests.Add(failedTest.Id); + } + } + } + } + + var duration = DateTime.UtcNow - startTime; + var executedTestIds = new TestIdentifierList(executedTests); + var failedTestIds = new TestIdentifierList(failedTests); + + return new TestRunResult( + _discoveredTests.Values, + executedTestIds, + failedTestIds, + TestIdentifierList.NoTest(), + failedTests.Any() ? $"{failedTests.Count} test(s) failed" : "All tests passed", + allMessages, + duration); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error running initial tests"); + return new TestRunResult(false, $"Initial test run failed: {ex.Message}"); + } + } + + public IEnumerable CaptureCoverage(IProjectAndTests project) + { + _logger.LogWarning("Coverage capture is not yet fully implemented for MTP runner"); + // Return empty coverage for now + return Enumerable.Empty(); + } + + public ITestRunResult TestMultipleMutants(IProjectAndTests project, ITimeoutValueCalculator timeoutCalc, + IReadOnlyList mutants, ITestRunner.TestUpdateHandler update) + { + _logger.LogInformation("Testing {Count} mutants", mutants.Count); + + try + { + var startTime = DateTime.UtcNow; + var allTests = GetTests(project); + var failedTests = new List(); + var executedTests = new List(); + + foreach (var assembly in project.GetTestAssemblies()) + { + if (!_testsPerAssembly.ContainsKey(assembly)) + { + continue; + } + + var timeout = timeoutCalc?.DefaultTimeout ?? 60000; + var result = RunDotnetTest(assembly, "", timeout: timeout); + + var assemblyTestIds = _testsPerAssembly[assembly]; + executedTests.AddRange(assemblyTestIds); + + if (result.ExitCode != 0) + { + var failedTestNames = ParseFailedTests(result.Output); + foreach (var failedName in failedTestNames) + { + var failedTest = _discoveredTests.Values.FirstOrDefault(t => t.Name == failedName && assemblyTestIds.Contains(t.Id)); + if (failedTest != null) + { + failedTests.Add(failedTest.Id); + } + } + } + } + + var duration = DateTime.UtcNow - startTime; + var executedTestIds = new TestIdentifierList(executedTests); + var failedTestIds = new TestIdentifierList(failedTests); + + return new TestRunResult( + _discoveredTests.Values, + executedTestIds, + failedTestIds, + TestIdentifierList.NoTest(), + failedTests.Any() ? $"{failedTests.Count} test(s) failed" : "All tests passed", + Array.Empty(), + duration); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error testing mutants"); + return new TestRunResult(false, $"Mutant testing failed: {ex.Message}"); + } + } + + private ProcessResult RunDotnetTest(string assembly, string additionalArgs, int timeout) + { + var projectDir = Path.GetDirectoryName(assembly); + var projectFile = Directory.GetFiles(projectDir, "*.csproj").FirstOrDefault(); + + if (string.IsNullOrEmpty(projectFile)) + { + _logger.LogError("No project file found in directory: {Directory}", projectDir); + return new ProcessResult { ExitCode = -1, Output = "No project file found" }; + } + + var startInfo = new ProcessStartInfo + { + FileName = "dotnet", + Arguments = $"test \"{projectFile}\" {additionalArgs} --no-build", + WorkingDirectory = projectDir, + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true + }; + + using var process = new Process { StartInfo = startInfo }; + var output = new System.Text.StringBuilder(); + var error = new System.Text.StringBuilder(); + + process.OutputDataReceived += (sender, e) => { if (e.Data != null) output.AppendLine(e.Data); }; + process.ErrorDataReceived += (sender, e) => { if (e.Data != null) error.AppendLine(e.Data); }; + + process.Start(); + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + + if (!process.WaitForExit(timeout)) + { + _logger.LogWarning("Test process timed out after {Timeout}ms", timeout); + try { process.Kill(); } catch { } + return new ProcessResult { ExitCode = -1, Output = "Process timed out", TimedOut = true }; + } + + var allOutput = output.ToString() + error.ToString(); + return new ProcessResult { ExitCode = process.ExitCode, Output = allOutput }; + } + + private List ParseListTestsOutput(string output) + { + var tests = new List(); + var lines = output.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); + + foreach (var line in lines) + { + var trimmed = line.Trim(); + // Test names typically start with namespace or are indented + if (trimmed.Contains('.') && !trimmed.StartsWith("Test run") && !trimmed.StartsWith("Passed!")) + { + tests.Add(trimmed); + } + } + + return tests; + } + + private List ParseFailedTests(string output) + { + var failedTests = new List(); + var lines = output.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); + + foreach (var line in lines) + { + if (line.Contains("Failed") || line.Contains("✗") || line.Contains("[FAIL]")) + { + // Try to extract test name from the line + var parts = line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); + foreach (var part in parts) + { + if (part.Contains('.') && !part.Contains("ms")) + { + failedTests.Add(part.Trim()); + break; + } + } + } + } + + return failedTests; + } + + public void Dispose() + { + _logger.LogDebug("Disposing MicrosoftTestingPlatformRunner"); + _discoveredTests.Clear(); + _testsPerAssembly.Clear(); + } + + private class ProcessResult + { + public int ExitCode { get; set; } + public string Output { get; set; } = string.Empty; + public bool TimedOut { get; set; } + } +} + +/// +/// Test description for MTP tests +/// +internal class MtpTestDescription : IFrameworkTestDescription +{ + private readonly List _initialResults = new(); + private int _subCases = 0; + + public MtpTestDescription(string id, string name, string filePath) + { + Id = id; + Name = name; + Description = new TestDescription(id, name, filePath); + Case = new MtpTestCase(id, name, filePath); + } + + public string Id { get; } + public string Name { get; } + public ITestDescription Description { get; } + public TestFrameworks Framework => TestFrameworks.MsTest; // Default to MsTest for now + public TimeSpan InitialRunTime => TimeSpan.FromTicks(_initialResults.Sum(r => r.Duration.Ticks)); + public int NbSubCases => _subCases; + public ITestCase Case { get; } + + public void RegisterInitialTestResult(ITestResult result) + { + _initialResults.Add(result); + } + + public void AddSubCase() + { + _subCases++; + } + + public void ClearInitialResult() + { + _initialResults.Clear(); + _subCases = 0; + } +} + +/// +/// Test case for MTP tests +/// +internal class MtpTestCase : ITestCase +{ + public MtpTestCase(string id, string name, string filePath) + { + Id = id; + Guid = Guid.TryParse(id, out var guid) ? guid : Guid.NewGuid(); + Name = name; + FullyQualifiedName = name; + CodeFilePath = filePath; + Source = filePath; + Uri = new Uri("executor://MicrosoftTestingPlatform/v1"); + LineNumber = 0; + } + + public string Id { get; } + public Guid Guid { get; } + public string Name { get; } + public string Source { get; } + public string CodeFilePath { get; } + public string FullyQualifiedName { get; } + public Uri Uri { get; } + public int LineNumber { get; } +} + +/// +/// Test set for MTP tests +/// +internal class MtpTestSet : ITestSet +{ + private readonly Dictionary _tests = new(); + + public MtpTestSet(IEnumerable tests) + { + foreach (var test in tests) + { + _tests[test.Id] = test.Description; + } + } + + public int Count => _tests.Count; + + public ITestDescription this[string id] => _tests.TryGetValue(id, out var test) ? test : throw new KeyNotFoundException($"Test with id {id} not found"); + + public void RegisterTests(IEnumerable tests) + { + foreach (var test in tests) + { + _tests[test.Id] = test; + } + } + + public void RegisterTest(ITestDescription test) + { + _tests[test.Id] = test; + } + + public IEnumerable Extract(IEnumerable ids) + { + return ids.Select(id => _tests.TryGetValue(id, out var test) ? test : null) + .Where(t => t != null)!; + } +} diff --git a/src/Stryker.TestRunner.MTP/Stryker.TestRunner.MTP.csproj b/src/Stryker.TestRunner.MTP/Stryker.TestRunner.MTP.csproj new file mode 100644 index 000000000..a8044da28 --- /dev/null +++ b/src/Stryker.TestRunner.MTP/Stryker.TestRunner.MTP.csproj @@ -0,0 +1,20 @@ + + + + net8.0 + enable + + + + + + + + + + + + + + + diff --git a/src/Stryker.TestRunner.MTP/packages.lock.json b/src/Stryker.TestRunner.MTP/packages.lock.json new file mode 100644 index 000000000..ade742a6c --- /dev/null +++ b/src/Stryker.TestRunner.MTP/packages.lock.json @@ -0,0 +1,397 @@ +{ + "version": 2, + "dependencies": { + "net8.0": { + "DotNet.ReproducibleBuilds": { + "type": "Direct", + "requested": "[1.2.39, )", + "resolved": "1.2.39", + "contentHash": "fcFN01tDTIQqDuTwr1jUQK/geofiwjG5DycJQOnC72i1SsLAk1ELe+apBOuZ11UMQG8YKFZG1FgvjZPbqHyatg==" + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Direct", + "requested": "[9.0.9, )", + "resolved": "9.0.9", + "contentHash": "FEgpSF+Z9StMvrsSViaybOBwR0f0ZZxDm8xV5cSOFiXN/t+ys+rwAlTd/6yG7Ld1gfppgvLcMasZry3GsI9lGA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.9", + "System.Diagnostics.DiagnosticSource": "9.0.9" + } + }, + "Microsoft.Testing.Extensions.TrxReport": { + "type": "Direct", + "requested": "[1.5.0, )", + "resolved": "1.5.0", + "contentHash": "+AW10NEScLAiErRKzek5U1Kv0B337EktcLt6ruzJXFTbtdQgK+3j0jxWbnfSs1N+R1eX2AsNF9/en7hWW8DDfg==", + "dependencies": { + "Microsoft.Testing.Extensions.TrxReport.Abstractions": "1.5.0", + "Microsoft.Testing.Platform": "1.5.0" + } + }, + "Microsoft.Testing.Platform": { + "type": "Direct", + "requested": "[1.5.0, )", + "resolved": "1.5.0", + "contentHash": "L6MsgthfCEuqx4Z3VWmUzilFN4I4hrRIXY0UgGTP9sv9upt1V9m5x9m7fWUKRrnzoE8yTFeRxw1KaI9XmXIzRA==" + }, + "Buildalyzer.Logger": { + "type": "Transitive", + "resolved": "7.1.0", + "contentHash": "a0T+Se+HSCxOvP2s7kUbgHBVeeJghliN9CO3pSl8JfqPhKD9JaE7ZxS3iTEgKglDsRibcqbdIxhYvvvIdLOvuQ==" + }, + "Microsoft.Build": { + "type": "Transitive", + "resolved": "17.10.4", + "contentHash": "ZmGA8vhVXFzC4oo48ybQKlEybVKd0Ntfdr+Enqrn5ES1R6e/krIK9hLk0W33xuT0/G6QYd3YdhJZh+Xle717Ag==", + "dependencies": { + "Microsoft.Build.Framework": "17.10.4", + "Microsoft.NET.StringTools": "17.10.4", + "System.Collections.Immutable": "8.0.0", + "System.Configuration.ConfigurationManager": "8.0.0", + "System.Reflection.Metadata": "8.0.0", + "System.Reflection.MetadataLoadContext": "8.0.0", + "System.Security.Principal.Windows": "5.0.0", + "System.Threading.Tasks.Dataflow": "8.0.0" + } + }, + "Microsoft.Build.Framework": { + "type": "Transitive", + "resolved": "17.10.4", + "contentHash": "4qXCwNOXBR1dyCzuks9SwTwFJQO/xmf2wcMislotDWJu7MN/r3xDNoU8Ae5QmKIHPaLG1xmfDkYS7qBVzxmeKw==" + }, + "Microsoft.Build.Tasks.Core": { + "type": "Transitive", + "resolved": "17.10.4", + "contentHash": "k1sefpk2VvJNwcexMjisH+TdzhspCVRtYvh4fAez5qRM20VvsNxcOIjfDe3h3StZRIGI2aiFKGxBZYkwM+WV+A==", + "dependencies": { + "Microsoft.Build.Framework": "17.10.4", + "Microsoft.Build.Utilities.Core": "17.10.4", + "Microsoft.NET.StringTools": "17.10.4", + "System.CodeDom": "8.0.0", + "System.Collections.Immutable": "8.0.0", + "System.Configuration.ConfigurationManager": "8.0.0", + "System.Resources.Extensions": "8.0.0", + "System.Security.Cryptography.Pkcs": "8.0.0", + "System.Security.Cryptography.Xml": "8.0.0" + } + }, + "Microsoft.Build.Utilities.Core": { + "type": "Transitive", + "resolved": "17.10.4", + "contentHash": "eEB/tcXkSV+nQgvoa/l53UPtn+KVtKZ8zBceDZsXVTrfE4fA+4+/olrx9W8n2tq4XiESsL9UuGJgCKzqBwQCoQ==", + "dependencies": { + "Microsoft.Build.Framework": "17.10.4", + "Microsoft.NET.StringTools": "17.10.4", + "System.Collections.Immutable": "8.0.0", + "System.Configuration.ConfigurationManager": "8.0.0" + } + }, + "Microsoft.Extensions.DependencyInjection": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "k6PWQMuoBDGGHOQTtyois2u4AwyVcIwL2LaSLlTZQm2CYcJ1pxbt6jfAnpWmzENA/wfrYRI/X9DTLoUkE4AsLw==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "9.0.9", + "contentHash": "/hymojfWbE9AlDOa0mczR44m00Jj+T3+HZO0ZnVTI032fVycI0ZbNOVFP6kqZMcXiLSYXzR2ilcwaRi6dzeGyA==" + }, + "Microsoft.Extensions.Options": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "dzXN0+V1AyjOe2xcJ86Qbo233KHuLEY0njf/P2Kw8SfJU+d45HNS2ctJdnEnrWbM9Ye2eFgaC5Mj9otRMU6IsQ==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" + } + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "9+PnzmQFfEFNR9J2aDTfJGGupShHjOuGw4VUv+JB044biSHrnmCIMD+mJHmb2H7YryrfBEXDurxQ47gJZdCKNQ==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "Microsoft.NET.StringTools": { + "type": "Transitive", + "resolved": "17.10.4", + "contentHash": "wyABaqY+IHCMMSTQmcc3Ca6vbmg5BaEPgicnEgpll+4xyWZWlkQqUwafweUd9VAhBb4jqplMl6voUHQ6yfdUcg==" + }, + "Microsoft.Testing.Extensions.TrxReport.Abstractions": { + "type": "Transitive", + "resolved": "1.5.0", + "contentHash": "3vMXWbqqy3rSXYlPshR7CPqG0bgGDOhasyhVtqhAOy2tMED6VKU/IbKNMUmEuqgPNjMkCaicDTfNdXsrJPKcsw==", + "dependencies": { + "Microsoft.Testing.Platform": "1.5.0" + } + }, + "MSBuild.StructuredLogger": { + "type": "Transitive", + "resolved": "2.2.158", + "contentHash": "A7hI65/MrDKdPpu4rsnqimDdAs42B05gpfOIyzWPJ+pqw6Q3p4r1I/AjWVe3joKGHIQSpL+0AX2tzLVVCaR0ug==", + "dependencies": { + "Microsoft.Build.Framework": "17.5.0", + "Microsoft.Build.Utilities.Core": "17.5.0" + } + }, + "MsBuildPipeLogger.Server": { + "type": "Transitive", + "resolved": "1.1.6", + "contentHash": "rls0hb7plSfVFCqScDxTqtGpIlMfoQEchqjmK/YtXDML11GU5jI+oCi9YsikGulJVUv/vLSY6Ktah0uXwv25EA==", + "dependencies": { + "Microsoft.Build": "15.3.409" + } + }, + "System.CodeDom": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "WTlRjL6KWIMr/pAaq3rYqh0TJlzpouaQ/W1eelssHgtlwHAH25jXTkUphTYx9HaIIf7XA6qs/0+YhtLEQRkJ+Q==" + }, + "System.Collections.Immutable": { + "type": "Transitive", + "resolved": "9.0.0", + "contentHash": "QhkXUl2gNrQtvPmtBTQHb0YsUrDiDQ2QS09YbtTTiSjGcf7NBqtYbrG/BE06zcBPCKEwQGzIv13IVdXNOSub2w==" + }, + "System.Configuration.ConfigurationManager": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "JlYi9XVvIREURRUlGMr1F6vOFLk7YSY4p1vHo4kX3tQ0AGrjqlRWHDi66ImHhy6qwXBG3BJ6Y1QlYQ+Qz6Xgww==", + "dependencies": { + "System.Diagnostics.EventLog": "8.0.0", + "System.Security.Cryptography.ProtectedData": "8.0.0" + } + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "9.0.9", + "contentHash": "8hy61dsFYYSDjT9iTAfygGMU3A0EAnG69x5FUXeKsCjMhBmtTBt4UMUEW3ipprFoorOW6Jw/7hDMjXtlrsOvVQ==" + }, + "System.Diagnostics.EventLog": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "fdYxcRjQqTTacKId/2IECojlDSFvp7LP5N78+0z/xH7v/Tuw5ZAxu23Y6PTCRinqyu2ePx+Gn1098NC6jM6d+A==" + }, + "System.Formats.Asn1": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "AJukBuLoe3QeAF+mfaRKQb2dgyrvt340iMBHYv+VdBzCUM06IxGlvl0o/uPOS7lHnXPN6u8fFRHSHudx5aTi8w==" + }, + "System.Reflection.Metadata": { + "type": "Transitive", + "resolved": "9.0.0", + "contentHash": "ANiqLu3DxW9kol/hMmTWbt3414t9ftdIuiIU7j80okq2YzAueo120M442xk1kDJWtmZTqWQn7wHDvMRipVOEOQ==", + "dependencies": { + "System.Collections.Immutable": "9.0.0" + } + }, + "System.Reflection.MetadataLoadContext": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "SZxrQ4sQYnIcdwiO3G/lHZopbPYQ2lW0ioT4JezgccWUrKaKbHLJbAGZaDfkYjWcta1pWssAo3MOXLsR0ie4tQ==", + "dependencies": { + "System.Collections.Immutable": "8.0.0", + "System.Reflection.Metadata": "8.0.0" + } + }, + "System.Resources.Extensions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "psnQ6GRQOvt+evda5C4nD5EuV49mz2Tv0DD2JDVDEbE/TKoMukxSkGJcsBJ0pajpPuFRr67syFYlkJ4Wj6A5Zw==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Security.Cryptography.Pkcs": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "ULmp3xoOwNYjOYp4JZ2NK/6NdTgiN1GQXzVVN1njQ7LOZ0d0B9vyMnhyqbIi9Qw4JXj1JgCsitkTShboHRx7Eg==", + "dependencies": { + "System.Formats.Asn1": "8.0.0" + } + }, + "System.Security.Cryptography.ProtectedData": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "+TUFINV2q2ifyXauQXRwy4CiBhqvDEDZeVJU7qfxya4aRYOKzVBpN+4acx25VcPB9ywUN6C0n8drWl110PhZEg==" + }, + "System.Security.Cryptography.Xml": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "HQSFbakswZ1OXFz2Bt3AJlC6ENDqWeVpgqhf213xqQUMDifzydOHIKVb1RV4prayobvR3ETIScMaQdDF2hwGZA==", + "dependencies": { + "System.Security.Cryptography.Pkcs": "8.0.0" + } + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + }, + "System.Threading.Tasks.Dataflow": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "7V0I8tPa9V7UxMx/+7DIwkhls5ouaEMQx6l/GwGm1Y8kJQ61On9B/PxCXFLbgu5/C47g0BP2CUYs+nMv1+Oaqw==" + }, + "Testably.Abstractions.FileSystem.Interface": { + "type": "Transitive", + "resolved": "9.0.0", + "contentHash": "uksk86YlnzAdyfVNu3wICU0X5iXVe9LF7Q3UkngNliHWEvM5gvAlOUr+jmd9JwmbJWISH5+i1vyXE02lEVz7WQ==" + }, + "stryker.abstractions": { + "type": "Project", + "dependencies": { + "Buildalyzer": "[7.1.0, )", + "DotNet.Glob": "[3.1.3, )", + "Microsoft.CodeAnalysis.CSharp": "[4.14.0, )", + "Microsoft.CodeAnalysis.Common": "[4.14.0, )", + "Microsoft.TestPlatform.ObjectModel": "[17.14.1, )", + "Serilog": "[4.3.0, )", + "TestableIO.System.IO.Abstractions.Wrappers": "[22.0.16, )" + } + }, + "stryker.testrunner": { + "type": "Project", + "dependencies": { + "Microsoft.TestPlatform.ObjectModel": "[17.14.1, )", + "Stryker.Abstractions": "[1.0.0, )", + "TestableIO.System.IO.Abstractions.Wrappers": "[22.0.16, )" + } + }, + "stryker.utilities": { + "type": "Project", + "dependencies": { + "Buildalyzer": "[7.1.0, )", + "Microsoft.CodeAnalysis.CSharp": "[4.14.0, )", + "Microsoft.CodeAnalysis.Common": "[4.14.0, )", + "Microsoft.Extensions.Logging.Abstractions": "[9.0.9, )", + "Mono.Cecil": "[0.11.6, )", + "ResXResourceReader.NetStandard": "[1.3.0, )", + "Stryker.Abstractions": "[1.0.0, )" + } + }, + "Buildalyzer": { + "type": "CentralTransitive", + "requested": "[7.1.0, )", + "resolved": "7.1.0", + "contentHash": "U6e7mHdQC672lfvqNVp70jQGb8g3aPnLafnFnnrzUwFfPX+4tK5uk3Ah+1R3svyG5kc3Qu9ZjBrhcvml/IwXrw==", + "dependencies": { + "Buildalyzer.Logger": "7.1.0", + "MSBuild.StructuredLogger": "2.2.158", + "Microsoft.Build": "17.10.4", + "Microsoft.Build.Tasks.Core": "17.10.4", + "Microsoft.CodeAnalysis.CSharp": "4.0.0", + "Microsoft.CodeAnalysis.VisualBasic": "4.0.0", + "Microsoft.Extensions.Logging": "6.0.0", + "MsBuildPipeLogger.Server": "1.1.6", + "NuGet.Frameworks": "6.9.1" + } + }, + "DotNet.Glob": { + "type": "CentralTransitive", + "requested": "[3.1.3, )", + "resolved": "3.1.3", + "contentHash": "hOfHw7MLJw/tbXaFwR1oiDb+dIXDp8URTxp5Pco42OOhiw77wrUNx6v6syNygHZbWwYdXQocL2Mo1l5FnfDVjg==" + }, + "Microsoft.CodeAnalysis.Analyzers": { + "type": "CentralTransitive", + "requested": "[4.14.0, )", + "resolved": "3.11.0", + "contentHash": "v/EW3UE8/lbEYHoC2Qq7AR/DnmvpgdtAMndfQNmpuIMx/Mto8L5JnuCfdBYtgvalQOtfNCnxFejxuRrryvUTsg==" + }, + "Microsoft.CodeAnalysis.Common": { + "type": "CentralTransitive", + "requested": "[4.14.0, )", + "resolved": "4.14.0", + "contentHash": "PC3tuwZYnC+idaPuoC/AZpEdwrtX7qFpmnrfQkgobGIWiYmGi5MCRtl5mx6QrfMGQpK78X2lfIEoZDLg/qnuHg==", + "dependencies": { + "Microsoft.CodeAnalysis.Analyzers": "3.11.0", + "System.Collections.Immutable": "9.0.0", + "System.Reflection.Metadata": "9.0.0" + } + }, + "Microsoft.CodeAnalysis.CSharp": { + "type": "CentralTransitive", + "requested": "[4.14.0, )", + "resolved": "4.14.0", + "contentHash": "568a6wcTivauIhbeWcCwfWwIn7UV7MeHEBvFB2uzGIpM2OhJ4eM/FZ8KS0yhPoNxnSpjGzz7x7CIjTxhslojQA==", + "dependencies": { + "Microsoft.CodeAnalysis.Analyzers": "3.11.0", + "Microsoft.CodeAnalysis.Common": "[4.14.0]", + "System.Collections.Immutable": "9.0.0", + "System.Reflection.Metadata": "9.0.0" + } + }, + "Microsoft.CodeAnalysis.VisualBasic": { + "type": "CentralTransitive", + "requested": "[4.14.0, )", + "resolved": "4.0.0", + "contentHash": "FK+OGUMUh9O6/GCwyIy4c/sOrarF36/yEY07BbXVYMql1qCqHGWfyWXyCQKQ6m/KqReCqW6aO4cK7kK/AYBpyA==", + "dependencies": { + "Microsoft.CodeAnalysis.Common": "[4.0.0]" + } + }, + "Microsoft.Extensions.Logging": { + "type": "CentralTransitive", + "requested": "[9.0.9, )", + "resolved": "6.0.0", + "contentHash": "eIbyj40QDg1NDz0HBW0S5f3wrLVnKWnDJ/JtZ+yJDFnDj90VoPuoPmFkeaXrtu+0cKm5GRAwoDf+dBWXK0TUdg==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "6.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Microsoft.Extensions.Options": "6.0.0", + "System.Diagnostics.DiagnosticSource": "6.0.0" + } + }, + "Microsoft.TestPlatform.ObjectModel": { + "type": "CentralTransitive", + "requested": "[17.14.1, )", + "resolved": "17.14.1", + "contentHash": "xTP1W6Mi6SWmuxd3a+jj9G9UoC850WGwZUps1Wah9r1ZxgXhdJfj1QqDLJkFjHDCvN42qDL2Ps5KjQYWUU0zcQ==", + "dependencies": { + "System.Reflection.Metadata": "8.0.0" + } + }, + "Mono.Cecil": { + "type": "CentralTransitive", + "requested": "[0.11.6, )", + "resolved": "0.11.6", + "contentHash": "f33RkDtZO8VlGXCtmQIviOtxgnUdym9xx/b1p9h91CRGOsJFxCFOFK1FDbVt1OCf1aWwYejUFa2MOQyFWTFjbA==" + }, + "NuGet.Frameworks": { + "type": "CentralTransitive", + "requested": "[6.14.0, )", + "resolved": "6.9.1", + "contentHash": "DaKh3lenPUvzGccPkbI97BIvA27z+/UsL3ankfoZlX/4vBVDK5N1sheFTQ+GuJf+IgSzsJz/A21SPUpQLHwUtA==" + }, + "ResXResourceReader.NetStandard": { + "type": "CentralTransitive", + "requested": "[1.3.0, )", + "resolved": "1.3.0", + "contentHash": "voW0VHwFGIvbJ4Pp/wfHKFGn9kxZD97H/mnD6LziBJCi4FJZtetYQpQQnpYp0IkL2+PQ6VOzkMvhK1+s7+NJnA==" + }, + "Serilog": { + "type": "CentralTransitive", + "requested": "[4.3.0, )", + "resolved": "4.3.0", + "contentHash": "+cDryFR0GRhsGOnZSKwaDzRRl4MupvJ42FhCE4zhQRVanX0Jpg6WuCBk59OVhVDPmab1bB+nRykAnykYELA9qQ==" + }, + "TestableIO.System.IO.Abstractions.Wrappers": { + "type": "CentralTransitive", + "requested": "[22.0.16, )", + "resolved": "22.0.16", + "contentHash": "QUX0TLMvnRLEgvuMRotrZKN9eCdX4yzK7HJCaPj17T4jvUf+G4XifdLpB5wmRct2zKlscYzpWMOmHjKabse3yw==", + "dependencies": { + "Testably.Abstractions.FileSystem.Interface": "9.0.0" + } + } + } + } +} \ No newline at end of file diff --git a/src/Stryker.TestRunner.VsTest.UnitTest/packages.lock.json b/src/Stryker.TestRunner.VsTest.UnitTest/packages.lock.json index ea88275b7..a48974dc8 100644 --- a/src/Stryker.TestRunner.VsTest.UnitTest/packages.lock.json +++ b/src/Stryker.TestRunner.VsTest.UnitTest/packages.lock.json @@ -264,15 +264,6 @@ "Microsoft.Testing.Platform": "1.9.0" } }, - "Microsoft.Testing.Extensions.TrxReport": { - "type": "Transitive", - "resolved": "1.9.0", - "contentHash": "/hcQOJ9Ktrz/nA90kUpN9mwZ4eWfiZLfO64Jq08Etf8YbidLtZFb3Xs/3v1amxAZ4nrTbQpmwr9X/aTs4LRBhQ==", - "dependencies": { - "Microsoft.Testing.Extensions.TrxReport.Abstractions": "1.9.0", - "Microsoft.Testing.Platform": "1.9.0" - } - }, "Microsoft.Testing.Extensions.TrxReport.Abstractions": { "type": "Transitive", "resolved": "1.9.0", @@ -293,11 +284,6 @@ "Microsoft.Testing.Platform": "1.9.0" } }, - "Microsoft.Testing.Platform": { - "type": "Transitive", - "resolved": "1.9.0", - "contentHash": "OE79Vc5rXwFYciAPY/mqv92XvdhK+pvCHdVHcS0bBpWwWQbnzI18FiSEEYY+lYpB0HHl0fDQgcCK3ZTYKGs8bA==" - }, "Microsoft.Testing.Platform.MSBuild": { "type": "Transitive", "resolved": "1.9.0", @@ -531,6 +517,11 @@ "resolved": "8.0.0", "contentHash": "ne1843evDugl0md7Fjzy6QjJrzsjh46ZKbhf8GwBXb5f/gw97J4bxMs0NQKifDuThh/f0bZ0e62NPl1jzTuRqA==" }, + "System.IO.Pipelines": { + "type": "Transitive", + "resolved": "9.0.9", + "contentHash": "VySjpsCLprojvat550Flrm3NQB982CPuDzILajqjQihFmrQXZPdQyktIbcpVPJyaExFYtAfY1DpwMdWQuS0kbw==" + }, "System.Management": { "type": "Transitive", "resolved": "6.0.1", @@ -753,13 +744,17 @@ }, "System.Text.Encodings.Web": { "type": "Transitive", - "resolved": "6.0.1", - "contentHash": "E5M5AE2OUTlCrf4omZvzzziUJO9CofBl+lXHaN5IKePPJvHqYFYYpaDPgCpR4VwaFbEebfnjOxxEBtPtsqAxpQ==" + "resolved": "9.0.9", + "contentHash": "bzYTmAcmfelUOCBxvbgsfSr2tq94ydA2gJZAxZRcuNa0LlmlVz8JNHst6RG1qsDujyVYT4vjv06y8sCLbvCXdg==" }, "System.Text.Json": { "type": "Transitive", - "resolved": "6.0.11", - "contentHash": "xqC1HIbJMBFhrpYs76oYP+NAskNVjc6v73HqLal7ECRDPIp4oRU5pPavkD//vNactCn9DA2aaald/I5N+uZ5/g==" + "resolved": "9.0.9", + "contentHash": "NEnpppwq67fRz/OvQRxsEMgetDJsxlxpEsAFO/4PZYbAyAMd4Ol6KS7phc8uDoKPsnbdzRLKobpX303uQwCqdg==", + "dependencies": { + "System.IO.Pipelines": "9.0.9", + "System.Text.Encodings.Web": "9.0.9" + } }, "System.Threading": { "type": "Transitive", @@ -829,13 +824,15 @@ "Serilog.Sinks.Console": "[6.0.0, )", "ShellProgressBar": "[5.2.0, )", "Spectre.Console": "[0.51.1, )", - "Stryker.Abstractions": "[4.8.1, )", - "Stryker.Configuration": "[4.8.1, )", - "Stryker.DataCollector": "[4.8.1, )", + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.Configuration": "[1.0.0, )", + "Stryker.DataCollector": "[1.0.0, )", "Stryker.Regex.Parser": "[1.0.0, )", - "Stryker.RegexMutators": "[4.8.1, )", - "Stryker.TestRunner.VsTest": "[4.8.1, )", - "Stryker.Utilities": "[4.8.1, )", + "Stryker.RegexMutators": "[1.0.0, )", + "Stryker.TestRunner": "[1.0.0, )", + "Stryker.TestRunner.MTP": "[1.0.0, )", + "Stryker.TestRunner.VsTest": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )", "TestableIO.System.IO.Abstractions.Wrappers": "[22.0.16, )" } }, @@ -858,8 +855,8 @@ "Microsoft.CodeAnalysis.CSharp": "[4.14.0, )", "Microsoft.CodeAnalysis.Common": "[4.14.0, )", "Serilog": "[4.3.0, )", - "Stryker.Abstractions": "[4.8.1, )", - "Stryker.Utilities": "[4.8.1, )" + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )" } }, "stryker.core.unittest": { @@ -872,9 +869,9 @@ "Moq": "[4.20.72, )", "Shouldly": "[4.3.0, )", "Spectre.Console.Testing": "[0.51.1, )", - "Stryker.Abstractions": "[4.8.1, )", + "Stryker.Abstractions": "[1.0.0, )", "Stryker.Regex.Parser": "[1.0.0, )", - "Stryker.Utilities": "[4.8.1, )", + "Stryker.Utilities": "[1.0.0, )", "TestableIO.System.IO.Abstractions.TestingHelpers": "[22.0.16, )", "stryker": "[4.8.1, )" } @@ -896,7 +893,20 @@ "type": "Project", "dependencies": { "Microsoft.TestPlatform.ObjectModel": "[17.14.1, )", - "Stryker.Abstractions": "[4.8.1, )" + "Stryker.Abstractions": "[1.0.0, )", + "TestableIO.System.IO.Abstractions.Wrappers": "[22.0.16, )" + } + }, + "stryker.testrunner.mtp": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "[9.0.9, )", + "Microsoft.Testing.Extensions.TrxReport": "[1.5.0, )", + "Microsoft.Testing.Platform": "[1.5.0, )", + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.TestRunner": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )", + "System.Net.Http.Json": "[9.0.9, )" } }, "stryker.testrunner.vstest": { @@ -907,10 +917,10 @@ "Microsoft.TestPlatform.ObjectModel": "[17.14.1, )", "Microsoft.TestPlatform.Portable": "[17.14.1, )", "Microsoft.TestPlatform.TranslationLayer": "[17.14.1, )", - "Stryker.Abstractions": "[4.8.1, )", - "Stryker.DataCollector": "[4.8.1, )", - "Stryker.TestRunner": "[4.8.1, )", - "Stryker.Utilities": "[4.8.1, )", + "Stryker.Abstractions": "[1.0.0, )", + "Stryker.DataCollector": "[1.0.0, )", + "Stryker.TestRunner": "[1.0.0, )", + "Stryker.Utilities": "[1.0.0, )", "TestableIO.System.IO.Abstractions.Wrappers": "[22.0.16, )" } }, @@ -923,7 +933,7 @@ "Microsoft.Extensions.Logging.Abstractions": "[9.0.9, )", "Mono.Cecil": "[0.11.6, )", "ResXResourceReader.NetStandard": "[1.3.0, )", - "Stryker.Abstractions": "[4.8.1, )" + "Stryker.Abstractions": "[1.0.0, )" } }, "Azure.Storage.Files.Shares": { @@ -1044,6 +1054,22 @@ "System.Diagnostics.DiagnosticSource": "9.0.9" } }, + "Microsoft.Testing.Extensions.TrxReport": { + "type": "CentralTransitive", + "requested": "[1.5.0, )", + "resolved": "1.9.0", + "contentHash": "/hcQOJ9Ktrz/nA90kUpN9mwZ4eWfiZLfO64Jq08Etf8YbidLtZFb3Xs/3v1amxAZ4nrTbQpmwr9X/aTs4LRBhQ==", + "dependencies": { + "Microsoft.Testing.Extensions.TrxReport.Abstractions": "1.9.0", + "Microsoft.Testing.Platform": "1.9.0" + } + }, + "Microsoft.Testing.Platform": { + "type": "CentralTransitive", + "requested": "[1.5.0, )", + "resolved": "1.9.0", + "contentHash": "OE79Vc5rXwFYciAPY/mqv92XvdhK+pvCHdVHcS0bBpWwWQbnzI18FiSEEYY+lYpB0HHl0fDQgcCK3ZTYKGs8bA==" + }, "Microsoft.TestPlatform": { "type": "CentralTransitive", "requested": "[17.14.1, )", @@ -1188,6 +1214,15 @@ "resolved": "1.0.0", "contentHash": "39OYYkvF2KlMbhxLBM+GTJEzPLu0HfN1v4AOApDFt3+ivd5F8HXwV5yp2A2+i7a7F5Tv2zr/7faCIqZj9c7x4g==" }, + "System.Net.Http.Json": { + "type": "CentralTransitive", + "requested": "[9.0.9, )", + "resolved": "9.0.9", + "contentHash": "Plss2+D6djmOMTkx/TbJ6vuz1bHjrhMXSj5DsjeWgK0PMRFPuc1Jo0TlFtgzbP3tMlG5U6Q+xB6ZwtMKRe1Ppw==", + "dependencies": { + "System.Text.Json": "9.0.9" + } + }, "TestableIO.System.IO.Abstractions.TestingHelpers": { "type": "CentralTransitive", "requested": "[22.0.16, )", diff --git a/src/Stryker.TestRunner.VsTest/packages.lock.json b/src/Stryker.TestRunner.VsTest/packages.lock.json index c5afeedbd..85afd4f9a 100644 --- a/src/Stryker.TestRunner.VsTest/packages.lock.json +++ b/src/Stryker.TestRunner.VsTest/packages.lock.json @@ -295,7 +295,8 @@ "type": "Project", "dependencies": { "Microsoft.TestPlatform.ObjectModel": "[17.14.1, )", - "Stryker.Abstractions": "[4.8.1, )" + "Stryker.Abstractions": "[1.0.0, )", + "TestableIO.System.IO.Abstractions.Wrappers": "[22.0.16, )" } }, "stryker.utilities": { @@ -307,7 +308,7 @@ "Microsoft.Extensions.Logging.Abstractions": "[9.0.9, )", "Mono.Cecil": "[0.11.6, )", "ResXResourceReader.NetStandard": "[1.3.0, )", - "Stryker.Abstractions": "[4.8.1, )" + "Stryker.Abstractions": "[1.0.0, )" } }, "Buildalyzer": { diff --git a/src/Stryker.TestRunner/Stryker.TestRunner.csproj b/src/Stryker.TestRunner/Stryker.TestRunner.csproj index 66be984b9..86736be4a 100644 --- a/src/Stryker.TestRunner/Stryker.TestRunner.csproj +++ b/src/Stryker.TestRunner/Stryker.TestRunner.csproj @@ -7,6 +7,7 @@ + diff --git a/src/Stryker.TestRunner/TestRunnerFactory.cs b/src/Stryker.TestRunner/TestRunnerFactory.cs new file mode 100644 index 000000000..1d1751439 --- /dev/null +++ b/src/Stryker.TestRunner/TestRunnerFactory.cs @@ -0,0 +1,56 @@ +using System; +using System.IO.Abstractions; +using Stryker.Abstractions.Options; +using Stryker.Abstractions.Testing; + +namespace Stryker.TestRunner; + +/// +/// Factory for creating test runners based on configuration +/// +public static class TestRunnerFactory +{ + /// + /// Creates a test runner instance based on the provided options + /// + /// Stryker options containing test runner configuration + /// Optional file system abstraction for testing + /// An ITestRunner instance + public static ITestRunner Create(IStrykerOptions options, IFileSystem fileSystem = null) + { + return options.TestRunner switch + { + Abstractions.Testing.TestRunner.VsTest => CreateVsTestRunner(options, fileSystem), + Abstractions.Testing.TestRunner.MicrosoftTestingPlatform => CreateMtpRunner(options), + _ => throw new ArgumentException($"Unknown test runner type: {options.TestRunner}", nameof(options)) + }; + } + + private static ITestRunner CreateVsTestRunner(IStrykerOptions options, IFileSystem fileSystem) + { + // VsTestRunnerPool is in a different project, so we use reflection to create it + var vsTestRunnerPoolType = Type.GetType("Stryker.TestRunner.VsTest.VsTestRunnerPool, Stryker.TestRunner.VsTest"); + + if (vsTestRunnerPoolType == null) + { + throw new InvalidOperationException("VsTest runner not found. Ensure Stryker.TestRunner.VsTest is referenced."); + } + + // Create instance using constructor: VsTestRunnerPool(IStrykerOptions options, IFileSystem fileSystem = null) + return (ITestRunner)Activator.CreateInstance(vsTestRunnerPoolType, options, fileSystem); + } + + private static ITestRunner CreateMtpRunner(IStrykerOptions options) + { + // MTP runner is in a different project, so we use reflection to create it + var mtpRunnerType = Type.GetType("Stryker.TestRunner.MTP.MicrosoftTestingPlatformRunner, Stryker.TestRunner.MTP"); + + if (mtpRunnerType == null) + { + throw new InvalidOperationException("Microsoft Testing Platform runner not found. Ensure Stryker.TestRunner.MTP is referenced."); + } + + // Create instance using constructor: MicrosoftTestingPlatformRunner(IStrykerOptions options) + return (ITestRunner)Activator.CreateInstance(mtpRunnerType, options); + } +} diff --git a/src/Stryker.TestRunner/packages.lock.json b/src/Stryker.TestRunner/packages.lock.json index 784d7a316..9a10651fd 100644 --- a/src/Stryker.TestRunner/packages.lock.json +++ b/src/Stryker.TestRunner/packages.lock.json @@ -17,6 +17,15 @@ "System.Reflection.Metadata": "8.0.0" } }, + "TestableIO.System.IO.Abstractions.Wrappers": { + "type": "Direct", + "requested": "[22.0.16, )", + "resolved": "22.0.16", + "contentHash": "QUX0TLMvnRLEgvuMRotrZKN9eCdX4yzK7HJCaPj17T4jvUf+G4XifdLpB5wmRct2zKlscYzpWMOmHjKabse3yw==", + "dependencies": { + "Testably.Abstractions.FileSystem.Interface": "9.0.0" + } + }, "Buildalyzer.Logger": { "type": "Transitive", "resolved": "7.1.0", @@ -325,15 +334,6 @@ "requested": "[4.3.0, )", "resolved": "4.3.0", "contentHash": "+cDryFR0GRhsGOnZSKwaDzRRl4MupvJ42FhCE4zhQRVanX0Jpg6WuCBk59OVhVDPmab1bB+nRykAnykYELA9qQ==" - }, - "TestableIO.System.IO.Abstractions.Wrappers": { - "type": "CentralTransitive", - "requested": "[22.0.16, )", - "resolved": "22.0.16", - "contentHash": "QUX0TLMvnRLEgvuMRotrZKN9eCdX4yzK7HJCaPj17T4jvUf+G4XifdLpB5wmRct2zKlscYzpWMOmHjKabse3yw==", - "dependencies": { - "Testably.Abstractions.FileSystem.Interface": "9.0.0" - } } } } diff --git a/src/Stryker.sln b/src/Stryker.sln index 78a544af3..b952d9ee0 100644 --- a/src/Stryker.sln +++ b/src/Stryker.sln @@ -58,64 +58,186 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stryker.TestRunner.VsTest", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stryker.TestRunner.VsTest.UnitTest", "Stryker.TestRunner.VsTest.UnitTest\Stryker.TestRunner.VsTest.UnitTest.csproj", "{CD0D00F0-E9B5-4F73-9A46-DA7CDB78BE61}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stryker.TestRunner.MTP", "Stryker.TestRunner.MTP\Stryker.TestRunner.MTP.csproj", "{1015FE68-ECF7-4AF7-B6F8-95E78C578AC0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {7B35D5F5-F983-4034-8A15-952E8C415010}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7B35D5F5-F983-4034-8A15-952E8C415010}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7B35D5F5-F983-4034-8A15-952E8C415010}.Debug|x64.ActiveCfg = Debug|Any CPU + {7B35D5F5-F983-4034-8A15-952E8C415010}.Debug|x64.Build.0 = Debug|Any CPU + {7B35D5F5-F983-4034-8A15-952E8C415010}.Debug|x86.ActiveCfg = Debug|Any CPU + {7B35D5F5-F983-4034-8A15-952E8C415010}.Debug|x86.Build.0 = Debug|Any CPU {7B35D5F5-F983-4034-8A15-952E8C415010}.Release|Any CPU.ActiveCfg = Release|Any CPU {7B35D5F5-F983-4034-8A15-952E8C415010}.Release|Any CPU.Build.0 = Release|Any CPU + {7B35D5F5-F983-4034-8A15-952E8C415010}.Release|x64.ActiveCfg = Release|Any CPU + {7B35D5F5-F983-4034-8A15-952E8C415010}.Release|x64.Build.0 = Release|Any CPU + {7B35D5F5-F983-4034-8A15-952E8C415010}.Release|x86.ActiveCfg = Release|Any CPU + {7B35D5F5-F983-4034-8A15-952E8C415010}.Release|x86.Build.0 = Release|Any CPU {1776E249-31B3-4357-94C8-13B86BEFD662}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1776E249-31B3-4357-94C8-13B86BEFD662}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1776E249-31B3-4357-94C8-13B86BEFD662}.Debug|x64.ActiveCfg = Debug|Any CPU + {1776E249-31B3-4357-94C8-13B86BEFD662}.Debug|x64.Build.0 = Debug|Any CPU + {1776E249-31B3-4357-94C8-13B86BEFD662}.Debug|x86.ActiveCfg = Debug|Any CPU + {1776E249-31B3-4357-94C8-13B86BEFD662}.Debug|x86.Build.0 = Debug|Any CPU {1776E249-31B3-4357-94C8-13B86BEFD662}.Release|Any CPU.ActiveCfg = Release|Any CPU {1776E249-31B3-4357-94C8-13B86BEFD662}.Release|Any CPU.Build.0 = Release|Any CPU + {1776E249-31B3-4357-94C8-13B86BEFD662}.Release|x64.ActiveCfg = Release|Any CPU + {1776E249-31B3-4357-94C8-13B86BEFD662}.Release|x64.Build.0 = Release|Any CPU + {1776E249-31B3-4357-94C8-13B86BEFD662}.Release|x86.ActiveCfg = Release|Any CPU + {1776E249-31B3-4357-94C8-13B86BEFD662}.Release|x86.Build.0 = Release|Any CPU {FC692334-8360-4A94-8692-5768ADC5DD04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FC692334-8360-4A94-8692-5768ADC5DD04}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FC692334-8360-4A94-8692-5768ADC5DD04}.Debug|x64.ActiveCfg = Debug|Any CPU + {FC692334-8360-4A94-8692-5768ADC5DD04}.Debug|x64.Build.0 = Debug|Any CPU + {FC692334-8360-4A94-8692-5768ADC5DD04}.Debug|x86.ActiveCfg = Debug|Any CPU + {FC692334-8360-4A94-8692-5768ADC5DD04}.Debug|x86.Build.0 = Debug|Any CPU {FC692334-8360-4A94-8692-5768ADC5DD04}.Release|Any CPU.ActiveCfg = Release|Any CPU {FC692334-8360-4A94-8692-5768ADC5DD04}.Release|Any CPU.Build.0 = Release|Any CPU + {FC692334-8360-4A94-8692-5768ADC5DD04}.Release|x64.ActiveCfg = Release|Any CPU + {FC692334-8360-4A94-8692-5768ADC5DD04}.Release|x64.Build.0 = Release|Any CPU + {FC692334-8360-4A94-8692-5768ADC5DD04}.Release|x86.ActiveCfg = Release|Any CPU + {FC692334-8360-4A94-8692-5768ADC5DD04}.Release|x86.Build.0 = Release|Any CPU {DBF2BA4B-39BE-48BF-B220-9891608B014F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {DBF2BA4B-39BE-48BF-B220-9891608B014F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DBF2BA4B-39BE-48BF-B220-9891608B014F}.Debug|x64.ActiveCfg = Debug|Any CPU + {DBF2BA4B-39BE-48BF-B220-9891608B014F}.Debug|x64.Build.0 = Debug|Any CPU + {DBF2BA4B-39BE-48BF-B220-9891608B014F}.Debug|x86.ActiveCfg = Debug|Any CPU + {DBF2BA4B-39BE-48BF-B220-9891608B014F}.Debug|x86.Build.0 = Debug|Any CPU {DBF2BA4B-39BE-48BF-B220-9891608B014F}.Release|Any CPU.ActiveCfg = Release|Any CPU {DBF2BA4B-39BE-48BF-B220-9891608B014F}.Release|Any CPU.Build.0 = Release|Any CPU + {DBF2BA4B-39BE-48BF-B220-9891608B014F}.Release|x64.ActiveCfg = Release|Any CPU + {DBF2BA4B-39BE-48BF-B220-9891608B014F}.Release|x64.Build.0 = Release|Any CPU + {DBF2BA4B-39BE-48BF-B220-9891608B014F}.Release|x86.ActiveCfg = Release|Any CPU + {DBF2BA4B-39BE-48BF-B220-9891608B014F}.Release|x86.Build.0 = Release|Any CPU {C5C14231-5DA6-4E3C-802C-6D76C0222FE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C5C14231-5DA6-4E3C-802C-6D76C0222FE4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C5C14231-5DA6-4E3C-802C-6D76C0222FE4}.Debug|x64.ActiveCfg = Debug|Any CPU + {C5C14231-5DA6-4E3C-802C-6D76C0222FE4}.Debug|x64.Build.0 = Debug|Any CPU + {C5C14231-5DA6-4E3C-802C-6D76C0222FE4}.Debug|x86.ActiveCfg = Debug|Any CPU + {C5C14231-5DA6-4E3C-802C-6D76C0222FE4}.Debug|x86.Build.0 = Debug|Any CPU {C5C14231-5DA6-4E3C-802C-6D76C0222FE4}.Release|Any CPU.ActiveCfg = Release|Any CPU {C5C14231-5DA6-4E3C-802C-6D76C0222FE4}.Release|Any CPU.Build.0 = Release|Any CPU + {C5C14231-5DA6-4E3C-802C-6D76C0222FE4}.Release|x64.ActiveCfg = Release|Any CPU + {C5C14231-5DA6-4E3C-802C-6D76C0222FE4}.Release|x64.Build.0 = Release|Any CPU + {C5C14231-5DA6-4E3C-802C-6D76C0222FE4}.Release|x86.ActiveCfg = Release|Any CPU + {C5C14231-5DA6-4E3C-802C-6D76C0222FE4}.Release|x86.Build.0 = Release|Any CPU {4E6E67F9-1890-4A6A-885B-CD6D55B2FC49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4E6E67F9-1890-4A6A-885B-CD6D55B2FC49}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4E6E67F9-1890-4A6A-885B-CD6D55B2FC49}.Debug|x64.ActiveCfg = Debug|Any CPU + {4E6E67F9-1890-4A6A-885B-CD6D55B2FC49}.Debug|x64.Build.0 = Debug|Any CPU + {4E6E67F9-1890-4A6A-885B-CD6D55B2FC49}.Debug|x86.ActiveCfg = Debug|Any CPU + {4E6E67F9-1890-4A6A-885B-CD6D55B2FC49}.Debug|x86.Build.0 = Debug|Any CPU {4E6E67F9-1890-4A6A-885B-CD6D55B2FC49}.Release|Any CPU.ActiveCfg = Release|Any CPU {4E6E67F9-1890-4A6A-885B-CD6D55B2FC49}.Release|Any CPU.Build.0 = Release|Any CPU + {4E6E67F9-1890-4A6A-885B-CD6D55B2FC49}.Release|x64.ActiveCfg = Release|Any CPU + {4E6E67F9-1890-4A6A-885B-CD6D55B2FC49}.Release|x64.Build.0 = Release|Any CPU + {4E6E67F9-1890-4A6A-885B-CD6D55B2FC49}.Release|x86.ActiveCfg = Release|Any CPU + {4E6E67F9-1890-4A6A-885B-CD6D55B2FC49}.Release|x86.Build.0 = Release|Any CPU {7C8C7670-4636-4C56-9E3E-22B987337EF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7C8C7670-4636-4C56-9E3E-22B987337EF2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7C8C7670-4636-4C56-9E3E-22B987337EF2}.Debug|x64.ActiveCfg = Debug|Any CPU + {7C8C7670-4636-4C56-9E3E-22B987337EF2}.Debug|x64.Build.0 = Debug|Any CPU + {7C8C7670-4636-4C56-9E3E-22B987337EF2}.Debug|x86.ActiveCfg = Debug|Any CPU + {7C8C7670-4636-4C56-9E3E-22B987337EF2}.Debug|x86.Build.0 = Debug|Any CPU {7C8C7670-4636-4C56-9E3E-22B987337EF2}.Release|Any CPU.ActiveCfg = Release|Any CPU {7C8C7670-4636-4C56-9E3E-22B987337EF2}.Release|Any CPU.Build.0 = Release|Any CPU + {7C8C7670-4636-4C56-9E3E-22B987337EF2}.Release|x64.ActiveCfg = Release|Any CPU + {7C8C7670-4636-4C56-9E3E-22B987337EF2}.Release|x64.Build.0 = Release|Any CPU + {7C8C7670-4636-4C56-9E3E-22B987337EF2}.Release|x86.ActiveCfg = Release|Any CPU + {7C8C7670-4636-4C56-9E3E-22B987337EF2}.Release|x86.Build.0 = Release|Any CPU {C9E6C641-94C1-41D2-BAA4-8BFE42749FBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C9E6C641-94C1-41D2-BAA4-8BFE42749FBE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C9E6C641-94C1-41D2-BAA4-8BFE42749FBE}.Debug|x64.ActiveCfg = Debug|Any CPU + {C9E6C641-94C1-41D2-BAA4-8BFE42749FBE}.Debug|x64.Build.0 = Debug|Any CPU + {C9E6C641-94C1-41D2-BAA4-8BFE42749FBE}.Debug|x86.ActiveCfg = Debug|Any CPU + {C9E6C641-94C1-41D2-BAA4-8BFE42749FBE}.Debug|x86.Build.0 = Debug|Any CPU {C9E6C641-94C1-41D2-BAA4-8BFE42749FBE}.Release|Any CPU.ActiveCfg = Release|Any CPU {C9E6C641-94C1-41D2-BAA4-8BFE42749FBE}.Release|Any CPU.Build.0 = Release|Any CPU + {C9E6C641-94C1-41D2-BAA4-8BFE42749FBE}.Release|x64.ActiveCfg = Release|Any CPU + {C9E6C641-94C1-41D2-BAA4-8BFE42749FBE}.Release|x64.Build.0 = Release|Any CPU + {C9E6C641-94C1-41D2-BAA4-8BFE42749FBE}.Release|x86.ActiveCfg = Release|Any CPU + {C9E6C641-94C1-41D2-BAA4-8BFE42749FBE}.Release|x86.Build.0 = Release|Any CPU {E80FD63A-510D-49E2-B1FE-B6CDD5BA106D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E80FD63A-510D-49E2-B1FE-B6CDD5BA106D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E80FD63A-510D-49E2-B1FE-B6CDD5BA106D}.Debug|x64.ActiveCfg = Debug|Any CPU + {E80FD63A-510D-49E2-B1FE-B6CDD5BA106D}.Debug|x64.Build.0 = Debug|Any CPU + {E80FD63A-510D-49E2-B1FE-B6CDD5BA106D}.Debug|x86.ActiveCfg = Debug|Any CPU + {E80FD63A-510D-49E2-B1FE-B6CDD5BA106D}.Debug|x86.Build.0 = Debug|Any CPU {E80FD63A-510D-49E2-B1FE-B6CDD5BA106D}.Release|Any CPU.ActiveCfg = Release|Any CPU {E80FD63A-510D-49E2-B1FE-B6CDD5BA106D}.Release|Any CPU.Build.0 = Release|Any CPU + {E80FD63A-510D-49E2-B1FE-B6CDD5BA106D}.Release|x64.ActiveCfg = Release|Any CPU + {E80FD63A-510D-49E2-B1FE-B6CDD5BA106D}.Release|x64.Build.0 = Release|Any CPU + {E80FD63A-510D-49E2-B1FE-B6CDD5BA106D}.Release|x86.ActiveCfg = Release|Any CPU + {E80FD63A-510D-49E2-B1FE-B6CDD5BA106D}.Release|x86.Build.0 = Release|Any CPU {BDD19501-B2E3-4EFE-ACCD-8D11C99CCCED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BDD19501-B2E3-4EFE-ACCD-8D11C99CCCED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BDD19501-B2E3-4EFE-ACCD-8D11C99CCCED}.Debug|x64.ActiveCfg = Debug|Any CPU + {BDD19501-B2E3-4EFE-ACCD-8D11C99CCCED}.Debug|x64.Build.0 = Debug|Any CPU + {BDD19501-B2E3-4EFE-ACCD-8D11C99CCCED}.Debug|x86.ActiveCfg = Debug|Any CPU + {BDD19501-B2E3-4EFE-ACCD-8D11C99CCCED}.Debug|x86.Build.0 = Debug|Any CPU {BDD19501-B2E3-4EFE-ACCD-8D11C99CCCED}.Release|Any CPU.ActiveCfg = Release|Any CPU {BDD19501-B2E3-4EFE-ACCD-8D11C99CCCED}.Release|Any CPU.Build.0 = Release|Any CPU + {BDD19501-B2E3-4EFE-ACCD-8D11C99CCCED}.Release|x64.ActiveCfg = Release|Any CPU + {BDD19501-B2E3-4EFE-ACCD-8D11C99CCCED}.Release|x64.Build.0 = Release|Any CPU + {BDD19501-B2E3-4EFE-ACCD-8D11C99CCCED}.Release|x86.ActiveCfg = Release|Any CPU + {BDD19501-B2E3-4EFE-ACCD-8D11C99CCCED}.Release|x86.Build.0 = Release|Any CPU {A19D156E-844E-4C8F-8D82-6051CBFBF910}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A19D156E-844E-4C8F-8D82-6051CBFBF910}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A19D156E-844E-4C8F-8D82-6051CBFBF910}.Debug|x64.ActiveCfg = Debug|Any CPU + {A19D156E-844E-4C8F-8D82-6051CBFBF910}.Debug|x64.Build.0 = Debug|Any CPU + {A19D156E-844E-4C8F-8D82-6051CBFBF910}.Debug|x86.ActiveCfg = Debug|Any CPU + {A19D156E-844E-4C8F-8D82-6051CBFBF910}.Debug|x86.Build.0 = Debug|Any CPU {A19D156E-844E-4C8F-8D82-6051CBFBF910}.Release|Any CPU.ActiveCfg = Release|Any CPU {A19D156E-844E-4C8F-8D82-6051CBFBF910}.Release|Any CPU.Build.0 = Release|Any CPU + {A19D156E-844E-4C8F-8D82-6051CBFBF910}.Release|x64.ActiveCfg = Release|Any CPU + {A19D156E-844E-4C8F-8D82-6051CBFBF910}.Release|x64.Build.0 = Release|Any CPU + {A19D156E-844E-4C8F-8D82-6051CBFBF910}.Release|x86.ActiveCfg = Release|Any CPU + {A19D156E-844E-4C8F-8D82-6051CBFBF910}.Release|x86.Build.0 = Release|Any CPU {978D9AD1-A9B7-483E-A204-EF13A55A92E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {978D9AD1-A9B7-483E-A204-EF13A55A92E4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {978D9AD1-A9B7-483E-A204-EF13A55A92E4}.Debug|x64.ActiveCfg = Debug|Any CPU + {978D9AD1-A9B7-483E-A204-EF13A55A92E4}.Debug|x64.Build.0 = Debug|Any CPU + {978D9AD1-A9B7-483E-A204-EF13A55A92E4}.Debug|x86.ActiveCfg = Debug|Any CPU + {978D9AD1-A9B7-483E-A204-EF13A55A92E4}.Debug|x86.Build.0 = Debug|Any CPU {978D9AD1-A9B7-483E-A204-EF13A55A92E4}.Release|Any CPU.ActiveCfg = Release|Any CPU {978D9AD1-A9B7-483E-A204-EF13A55A92E4}.Release|Any CPU.Build.0 = Release|Any CPU + {978D9AD1-A9B7-483E-A204-EF13A55A92E4}.Release|x64.ActiveCfg = Release|Any CPU + {978D9AD1-A9B7-483E-A204-EF13A55A92E4}.Release|x64.Build.0 = Release|Any CPU + {978D9AD1-A9B7-483E-A204-EF13A55A92E4}.Release|x86.ActiveCfg = Release|Any CPU + {978D9AD1-A9B7-483E-A204-EF13A55A92E4}.Release|x86.Build.0 = Release|Any CPU {CD0D00F0-E9B5-4F73-9A46-DA7CDB78BE61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CD0D00F0-E9B5-4F73-9A46-DA7CDB78BE61}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CD0D00F0-E9B5-4F73-9A46-DA7CDB78BE61}.Debug|x64.ActiveCfg = Debug|Any CPU + {CD0D00F0-E9B5-4F73-9A46-DA7CDB78BE61}.Debug|x64.Build.0 = Debug|Any CPU + {CD0D00F0-E9B5-4F73-9A46-DA7CDB78BE61}.Debug|x86.ActiveCfg = Debug|Any CPU + {CD0D00F0-E9B5-4F73-9A46-DA7CDB78BE61}.Debug|x86.Build.0 = Debug|Any CPU {CD0D00F0-E9B5-4F73-9A46-DA7CDB78BE61}.Release|Any CPU.ActiveCfg = Release|Any CPU {CD0D00F0-E9B5-4F73-9A46-DA7CDB78BE61}.Release|Any CPU.Build.0 = Release|Any CPU + {CD0D00F0-E9B5-4F73-9A46-DA7CDB78BE61}.Release|x64.ActiveCfg = Release|Any CPU + {CD0D00F0-E9B5-4F73-9A46-DA7CDB78BE61}.Release|x64.Build.0 = Release|Any CPU + {CD0D00F0-E9B5-4F73-9A46-DA7CDB78BE61}.Release|x86.ActiveCfg = Release|Any CPU + {CD0D00F0-E9B5-4F73-9A46-DA7CDB78BE61}.Release|x86.Build.0 = Release|Any CPU + {1015FE68-ECF7-4AF7-B6F8-95E78C578AC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1015FE68-ECF7-4AF7-B6F8-95E78C578AC0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1015FE68-ECF7-4AF7-B6F8-95E78C578AC0}.Debug|x64.ActiveCfg = Debug|Any CPU + {1015FE68-ECF7-4AF7-B6F8-95E78C578AC0}.Debug|x64.Build.0 = Debug|Any CPU + {1015FE68-ECF7-4AF7-B6F8-95E78C578AC0}.Debug|x86.ActiveCfg = Debug|Any CPU + {1015FE68-ECF7-4AF7-B6F8-95E78C578AC0}.Debug|x86.Build.0 = Debug|Any CPU + {1015FE68-ECF7-4AF7-B6F8-95E78C578AC0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1015FE68-ECF7-4AF7-B6F8-95E78C578AC0}.Release|Any CPU.Build.0 = Release|Any CPU + {1015FE68-ECF7-4AF7-B6F8-95E78C578AC0}.Release|x64.ActiveCfg = Release|Any CPU + {1015FE68-ECF7-4AF7-B6F8-95E78C578AC0}.Release|x64.Build.0 = Release|Any CPU + {1015FE68-ECF7-4AF7-B6F8-95E78C578AC0}.Release|x86.ActiveCfg = Release|Any CPU + {1015FE68-ECF7-4AF7-B6F8-95E78C578AC0}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE