diff --git a/GoogleTestAdapter/Core.Tests/GoogleTestExecutorTests.cs b/GoogleTestAdapter/Core.Tests/GoogleTestExecutorTests.cs index 51742aece..f5891d8bb 100644 --- a/GoogleTestAdapter/Core.Tests/GoogleTestExecutorTests.cs +++ b/GoogleTestAdapter/Core.Tests/GoogleTestExecutorTests.cs @@ -44,7 +44,7 @@ private void AssertDurationsFileIsCreated(bool parallelExecution) var collectingReporter = new FakeFrameworkReporter(); var testExecutor = new GoogleTestExecutor(TestEnvironment.Logger, TestEnvironment.Options); - testExecutor.RunTests(TestDataCreator.AllTestCasesExceptLoadTests, TestDataCreator.AllTestCasesExceptLoadTests, collectingReporter, null, false, TestResources.SampleTestsSolutionDir, processExecutor); + testExecutor.RunTests(TestDataCreator.AllTestCasesExceptLoadTests, collectingReporter, null, false, TestResources.SampleTestsSolutionDir, processExecutor); sampleTestsDurationsFile.AsFileInfo() .Should() diff --git a/GoogleTestAdapter/Core.Tests/Runners/CommandLineGeneratorTests.cs b/GoogleTestAdapter/Core.Tests/Runners/CommandLineGeneratorTests.cs index 9d3422db4..a3339f7d7 100644 --- a/GoogleTestAdapter/Core.Tests/Runners/CommandLineGeneratorTests.cs +++ b/GoogleTestAdapter/Core.Tests/Runners/CommandLineGeneratorTests.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using FluentAssertions; +using GoogleTestAdapter.Helpers; using GoogleTestAdapter.Settings; using GoogleTestAdapter.Tests.Common; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -25,7 +26,7 @@ public void Constructor_UserParametersNull_Throws() Action a = () => // ReSharper disable once ObjectCreationAsStatement - new CommandLineGenerator(new List(), new List(), 0, null, "", + new CommandLineGenerator(new List(), 0, null, "", TestEnvironment.Options); a.ShouldThrow(); } @@ -36,7 +37,7 @@ public void GetCommandLines_AdditionalArguments_AreAppendedCorrectly() { string userParameters = "-testdirectory=\"MyTestDirectory\""; - string commandLine = new CommandLineGenerator(new List(), new List(), TestDataCreator.DummyExecutable.Length, userParameters, "", TestEnvironment.Options).GetCommandLines().First().CommandLine; + string commandLine = new CommandLineGenerator(new List(), TestDataCreator.DummyExecutable.Length, userParameters, "", TestEnvironment.Options).GetCommandLines().First().CommandLine; commandLine.Should().EndWith(" -testdirectory=\"MyTestDirectory\""); } @@ -46,7 +47,7 @@ public void GetCommandLines_AdditionalArguments_AreAppendedCorrectly() public void GetCommandLines_AllTests_ProducesCorrectArguments() { IEnumerable testCases = TestDataCreator.CreateDummyTestCases("Suite1.Test1 param", "Suite2.Test2"); - string commandLine = new CommandLineGenerator(testCases, testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options).GetCommandLines().First().CommandLine; + string commandLine = new CommandLineGenerator(testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options).GetCommandLines().First().CommandLine; commandLine.Should().Be($"--gtest_output=\"xml:\"{DefaultArgs}"); } @@ -56,13 +57,13 @@ public void GetCommandLines_AllTests_ProducesCorrectArguments() public void GetCommandLines_CatchExceptionsOption_IsAppendedCorrectly() { IEnumerable testCases = TestDataCreator.CreateDummyTestCases("Suite1.Test1", "Suite2.Test2"); - string commandLine = new CommandLineGenerator(testCases, testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options).GetCommandLines().First().CommandLine; + string commandLine = new CommandLineGenerator(testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options).GetCommandLines().First().CommandLine; string catchExceptionsOption = GoogleTestConstants.GetCatchExceptionsOption(true); commandLine.Should().Contain(catchExceptionsOption); MockOptions.Setup(o => o.CatchExceptions).Returns(false); - commandLine = new CommandLineGenerator(testCases, testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options).GetCommandLines().First().CommandLine; + commandLine = new CommandLineGenerator(testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options).GetCommandLines().First().CommandLine; catchExceptionsOption = GoogleTestConstants.GetCatchExceptionsOption(false); commandLine.Should().Contain(catchExceptionsOption); @@ -73,13 +74,13 @@ public void GetCommandLines_CatchExceptionsOption_IsAppendedCorrectly() public void GetCommandLines_BreakOnFailureOption_IsAppendedCorrectly() { IEnumerable testCases = TestDataCreator.CreateDummyTestCases("Suite1.Test1", "Suite2.Test2"); - string commandLine = new CommandLineGenerator(testCases, testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options).GetCommandLines().First().CommandLine; + string commandLine = new CommandLineGenerator(testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options).GetCommandLines().First().CommandLine; string breakOnFailureOption = GoogleTestConstants.GetBreakOnFailureOption(false); commandLine.Should().Contain(breakOnFailureOption); MockOptions.Setup(o => o.BreakOnFailure).Returns(true); - commandLine = new CommandLineGenerator(testCases, testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options).GetCommandLines().First().CommandLine; + commandLine = new CommandLineGenerator(testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options).GetCommandLines().First().CommandLine; breakOnFailureOption = GoogleTestConstants.GetBreakOnFailureOption(true); commandLine.Should().Contain(breakOnFailureOption); } @@ -91,7 +92,7 @@ public void GetCommandLines_RepetitionsOption_IsAppendedCorrectly() MockOptions.Setup(o => o.NrOfTestRepetitions).Returns(4711); IEnumerable testCases = TestDataCreator.CreateDummyTestCases("Suite1.Test1", "Suite2.Test2"); - string commandLine = new CommandLineGenerator(testCases, testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options).GetCommandLines().First().CommandLine; + string commandLine = new CommandLineGenerator(testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options).GetCommandLines().First().CommandLine; string repetitionsOption = GoogleTestConstants.NrOfRepetitionsOption + "=4711"; commandLine.Should().Be($"--gtest_output=\"xml:\"{DefaultArgs}{repetitionsOption}"); @@ -104,7 +105,7 @@ public void GetCommandLines_ShuffleTestsWithDefaultSeed_IsAppendedCorrectly() MockOptions.Setup(o => o.ShuffleTests).Returns(true); IEnumerable testCases = TestDataCreator.CreateDummyTestCases("Suite1.Test1", "Suite2.Test2"); - string commandLine = new CommandLineGenerator(testCases, testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options).GetCommandLines().First().CommandLine; + string commandLine = new CommandLineGenerator(testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options).GetCommandLines().First().CommandLine; commandLine.Should().Be($"--gtest_output=\"xml:\"{DefaultArgs}{GoogleTestConstants.ShuffleTestsOption}"); } @@ -117,7 +118,7 @@ public void GetCommandLines_ShuffleTestsWithCustomSeed_IsAppendedCorrectly() MockOptions.Setup(o => o.ShuffleTestsSeed).Returns(4711); IEnumerable testCases = TestDataCreator.CreateDummyTestCases("Suite1.Test1", "Suite2.Test2"); - string commandLine = new CommandLineGenerator(testCases, testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options).GetCommandLines().First().CommandLine; + string commandLine = new CommandLineGenerator(testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options).GetCommandLines().First().CommandLine; string shuffleTestsOption = GoogleTestConstants.ShuffleTestsOption + GoogleTestConstants.ShuffleTestsSeedOption + "=4711"; @@ -128,10 +129,11 @@ public void GetCommandLines_ShuffleTestsWithCustomSeed_IsAppendedCorrectly() [TestCategory(Unit)] public void GetCommandLines_TestsWithCommonSuite_AreCombinedViaSuite() { - IEnumerable testCasesWithCommonSuite = TestDataCreator.CreateDummyTestCases("FooSuite.BarTest", "FooSuite.BazTest"); - IEnumerable allTestCases = testCasesWithCommonSuite.Union(TestDataCreator.CreateDummyTestCases("BarSuite.FooTest")); + string[] testCaseNamesWithCommonSuite = { "FooSuite.BarTest", "FooSuite.BazTest" }; + string[] allTestCaseNames = testCaseNamesWithCommonSuite.Union("BarSuite.FooTest".Yield()).ToArray(); + IEnumerable testCasesWithCommonSuite = TestDataCreator.CreateDummyTestCasesFull(testCaseNamesWithCommonSuite, allTestCaseNames); - string commandLine = new CommandLineGenerator(allTestCases, testCasesWithCommonSuite, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options) + string commandLine = new CommandLineGenerator(testCasesWithCommonSuite, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options) .GetCommandLines().First().CommandLine; commandLine.Should().Be($"--gtest_output=\"xml:\"{DefaultArgs} --gtest_filter=FooSuite.*:"); @@ -141,13 +143,18 @@ public void GetCommandLines_TestsWithCommonSuite_AreCombinedViaSuite() [TestCategory(Unit)] public void GetCommandLines_ParameterizedTestsWithCommonSuite_AreCombinedViaSuite() { - IEnumerable testCasesWithCommonSuite = TestDataCreator.CreateDummyTestCases( + string[] testCaseNamesWithCommonSuite = + { "InstantiationName2/ParameterizedTests.SimpleTraits/0", "InstantiationName/ParameterizedTests.SimpleTraits/0", - "InstantiationName/ParameterizedTests.SimpleTraits/1"); - IEnumerable allTestCases = testCasesWithCommonSuite.Union(TestDataCreator.CreateDummyTestCases("InstantiationName2/ParameterizedTests.SimpleTraits/1 # GetParam() = (,2)")); - - string commandLine = new CommandLineGenerator(allTestCases, testCasesWithCommonSuite, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options) + "InstantiationName/ParameterizedTests.SimpleTraits/1" + }; + string[] allTestCaseNames = testCaseNamesWithCommonSuite + .Union("InstantiationName2/ParameterizedTests.SimpleTraits/1 # GetParam() = (,2)".Yield()) + .ToArray(); + IEnumerable testCasesWithCommonSuite = TestDataCreator.CreateDummyTestCasesFull(testCaseNamesWithCommonSuite, allTestCaseNames); + + string commandLine = new CommandLineGenerator(testCasesWithCommonSuite, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options) .GetCommandLines().First().CommandLine; commandLine.Should() @@ -159,14 +166,16 @@ public void GetCommandLines_ParameterizedTestsWithCommonSuite_AreCombinedViaSuit [TestCategory(Unit)] public void GetCommandLines_TestsWithCommonSuiteInReverseOrder_AreCombinedViaSuite() { - IEnumerable testCasesWithCommonSuite = TestDataCreator.CreateDummyTestCases("FooSuite.BarTest", "FooSuite.BazTest", - "FooSuite.gsdfgdfgsdfg", "FooSuite.23453452345", "FooSuite.bxcvbxcvbxcvb"); - IEnumerable allTestCases = testCasesWithCommonSuite.Union(TestDataCreator.CreateDummyTestCases("BarSuite.BarTest")); + string[] testCaseNamesWithCommonSuite = { "FooSuite.BarTest", "FooSuite.BazTest", + "FooSuite.gsdfgdfgsdfg", "FooSuite.23453452345", "FooSuite.bxcvbxcvbxcvb" }; + string[] allTestCaseNames = testCaseNamesWithCommonSuite.Union("BarSuite.BarTest".Yield()).ToArray(); + IEnumerable testCasesWithCommonSuite = TestDataCreator.CreateDummyTestCasesFull(testCaseNamesWithCommonSuite, allTestCaseNames); + IEnumerable testCasesReversed = testCasesWithCommonSuite.Reverse(); - string commandLine = new CommandLineGenerator(allTestCases, testCasesWithCommonSuite, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options) + string commandLine = new CommandLineGenerator(testCasesWithCommonSuite, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options) .GetCommandLines().First().CommandLine; - string commandLineFromBackwards = new CommandLineGenerator(allTestCases, testCasesReversed, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options) + string commandLineFromBackwards = new CommandLineGenerator(testCasesReversed, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options) .GetCommandLines().First().CommandLine; string expectedCommandLine = $"--gtest_output=\"xml:\"{DefaultArgs} --gtest_filter=FooSuite.*:"; @@ -178,10 +187,11 @@ public void GetCommandLines_TestsWithCommonSuiteInReverseOrder_AreCombinedViaSui [TestCategory(Unit)] public void GetCommandLines_TestsWithoutCommonSuite_AreNotCombined() { - IEnumerable testCasesWithDifferentSuite = TestDataCreator.CreateDummyTestCases("FooSuite.BarTest", "BarSuite.BazTest1"); - IEnumerable allTestCases = testCasesWithDifferentSuite.Union(TestDataCreator.CreateDummyTestCases("FooSuite.BazTest", "BarSuite.BazTest2")); + string[] testCaseNamesWithDifferentSuite = { "FooSuite.BarTest", "BarSuite.BazTest1" }; + string[] allTestCaseNames = testCaseNamesWithDifferentSuite.Union(new[]{ "FooSuite.BazTest", "BarSuite.BazTest2" }).ToArray(); + IEnumerable testCasesWithDifferentSuite = TestDataCreator.CreateDummyTestCasesFull(testCaseNamesWithDifferentSuite, allTestCaseNames); - string commandLine = new CommandLineGenerator(allTestCases, testCasesWithDifferentSuite, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options) + string commandLine = new CommandLineGenerator(testCasesWithDifferentSuite, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options) .GetCommandLines().First().CommandLine; commandLine.Should() @@ -192,10 +202,11 @@ public void GetCommandLines_TestsWithoutCommonSuite_AreNotCombined() [TestCategory(Unit)] public void GetCommandLines_TestsWithoutCommonSuiteInDifferentOrder_AreNotCombined() { - IEnumerable testCasesWithDifferentSuite = TestDataCreator.CreateDummyTestCases("BarSuite.BazTest1", "FooSuite.BarTest"); - IEnumerable allTestCases = testCasesWithDifferentSuite.Union(TestDataCreator.CreateDummyTestCases("FooSuite.BazTest", "BarSuite.BazTest2")); + string[] testCaseNamesWithDifferentSuite = { "BarSuite.BazTest1", "FooSuite.BarTest" }; + string[] allTestCaseNames = testCaseNamesWithDifferentSuite.Union(new[] { "FooSuite.BazTest", "BarSuite.BazTest2" }).ToArray(); + IEnumerable testCasesWithDifferentSuite = TestDataCreator.CreateDummyTestCasesFull(testCaseNamesWithDifferentSuite, allTestCaseNames); - string commandLine = new CommandLineGenerator(allTestCases, testCasesWithDifferentSuite, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options) + string commandLine = new CommandLineGenerator(testCasesWithDifferentSuite, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options) .GetCommandLines().First().CommandLine; commandLine.Should() @@ -210,14 +221,16 @@ public void GetCommandLines_ManyTests_BreaksUpLongCommandLinesCorrectly() List testsToExecute = new List(); for (int i = 0; i < 1000; i++) { - allTests.Add("MyTestSuite" + i + ".MyTest"); - testsToExecute.Add("MyTestSuite" + i + ".MyTest"); - allTests.Add("MyTestSuite" + i + ".MyTest2"); + string test1 = $"MyTestSuite{i}.MyTest"; + string test2 = $"MyTestSuite{i}.MyTest2"; + + allTests.Add(test1); + testsToExecute.Add(test1); + allTests.Add(test2); } - IEnumerable allTestCases = allTests.Select(TestDataCreator.ToTestCase).ToList(); - IEnumerable testCases = testsToExecute.Select(TestDataCreator.ToTestCase).ToList(); + IEnumerable testCases = TestDataCreator.CreateDummyTestCasesFull(testsToExecute.ToArray(), allTests.ToArray()); - List commands = new CommandLineGenerator(allTestCases, testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options) + List commands = new CommandLineGenerator(testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options) .GetCommandLines().ToList(); commands.Count.Should().Be(3); @@ -262,10 +275,9 @@ public void GetCommandLines_ManyTestsWithSuites_BreaksUpLongCommandLinesCorrectl testsToExecute.Add("MyTestSuite1.MyTest2"); testsToExecute.Add("MyTestSuite5.MyTest2"); - IEnumerable allTestCases = allTests.Select(TestDataCreator.ToTestCase).ToList(); - IEnumerable testCases = testsToExecute.Select(TestDataCreator.ToTestCase).ToList(); + IEnumerable testCases = TestDataCreator.CreateDummyTestCasesFull(testsToExecute.ToArray(), allTests.ToArray()); - List commands = new CommandLineGenerator(allTestCases, testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options) + List commands = new CommandLineGenerator(testCases, TestDataCreator.DummyExecutable.Length, "", "", TestEnvironment.Options) .GetCommandLines().ToList(); commands.Count.Should().Be(3); diff --git a/GoogleTestAdapter/Core.Tests/Runners/SequentialTestRunnerTests.cs b/GoogleTestAdapter/Core.Tests/Runners/SequentialTestRunnerTests.cs index 8f2d1b5a5..0540c2682 100644 --- a/GoogleTestAdapter/Core.Tests/Runners/SequentialTestRunnerTests.cs +++ b/GoogleTestAdapter/Core.Tests/Runners/SequentialTestRunnerTests.cs @@ -39,13 +39,12 @@ public void RunTests_CancelingAndKillingProcessesDuringTestExecution_StopsTestEx private void DoRunCancelingTests(bool killProcesses, int lower, int upper) { MockOptions.Setup(o => o.KillProcessesOnCancel).Returns(killProcesses); - List allTestCases = TestDataCreator.AllTestCasesExceptLoadTests; List testCasesToRun = TestDataCreator.GetTestCases("Crashing.LongRunning", "LongRunningTests.Test2"); var stopwatch = new Stopwatch(); var runner = new SequentialTestRunner("", MockFrameworkReporter.Object, TestEnvironment.Logger, TestEnvironment.Options, new SchedulingAnalyzer(TestEnvironment.Logger)); var executor = new ProcessExecutor(null, MockLogger.Object); - var thread = new Thread(() => runner.RunTests(allTestCases, testCasesToRun, "", "", "", false, null, executor)); + var thread = new Thread(() => runner.RunTests(testCasesToRun, "", "", "", false, null, executor)); stopwatch.Start(); thread.Start(); diff --git a/GoogleTestAdapter/Core/Core.csproj b/GoogleTestAdapter/Core/Core.csproj index 256ecaf16..69267623f 100644 --- a/GoogleTestAdapter/Core/Core.csproj +++ b/GoogleTestAdapter/Core/Core.csproj @@ -59,6 +59,8 @@ + + diff --git a/GoogleTestAdapter/Core/GoogleTestExecutor.cs b/GoogleTestAdapter/Core/GoogleTestExecutor.cs index cc84f982f..54146b140 100644 --- a/GoogleTestAdapter/Core/GoogleTestExecutor.cs +++ b/GoogleTestAdapter/Core/GoogleTestExecutor.cs @@ -28,7 +28,7 @@ public GoogleTestExecutor(ILogger logger, SettingsWrapper settings) } - public void RunTests(IEnumerable allTestCasesInExecutables, IEnumerable testCasesToRun, ITestFrameworkReporter reporter, IDebuggedProcessLauncher launcher, bool isBeingDebugged, string solutionDirectory, IProcessExecutor executor) + public void RunTests(IEnumerable testCasesToRun, ITestFrameworkReporter reporter, IDebuggedProcessLauncher launcher, bool isBeingDebugged, string solutionDirectory, IProcessExecutor executor) { TestCase[] testCasesToRunAsArray = testCasesToRun as TestCase[] ?? testCasesToRun.ToArray(); _logger.LogInfo("Running " + testCasesToRunAsArray.Length + " tests..."); @@ -42,7 +42,7 @@ public void RunTests(IEnumerable allTestCasesInExecutables, IEnumerabl ComputeTestRunner(reporter, isBeingDebugged, solutionDirectory); } - _runner.RunTests(allTestCasesInExecutables, testCasesToRunAsArray, solutionDirectory, null, null, isBeingDebugged, launcher, executor); + _runner.RunTests(testCasesToRunAsArray, solutionDirectory, null, null, isBeingDebugged, launcher, executor); if (_settings.ParallelTestExecution) _schedulingAnalyzer.PrintStatisticsToDebugOutput(); diff --git a/GoogleTestAdapter/Core/Model/TestCase.cs b/GoogleTestAdapter/Core/Model/TestCase.cs index 6ecf7b01c..44291bbf6 100644 --- a/GoogleTestAdapter/Core/Model/TestCase.cs +++ b/GoogleTestAdapter/Core/Model/TestCase.cs @@ -13,6 +13,7 @@ public class TestCase public int LineNumber { get; } public List Traits { get; } = new List(); + public List Properties { get; } = new List(); public TestCase(string fullyQualifiedName, string source, string displayName, string codeFilePath, int lineNumber) { diff --git a/GoogleTestAdapter/Core/Model/TestCaseMetaDataProperty.cs b/GoogleTestAdapter/Core/Model/TestCaseMetaDataProperty.cs new file mode 100644 index 000000000..af1a50f7f --- /dev/null +++ b/GoogleTestAdapter/Core/Model/TestCaseMetaDataProperty.cs @@ -0,0 +1,28 @@ +using System; +using System.Linq; + +namespace GoogleTestAdapter.Model +{ + public class TestCaseMetaDataProperty : TestProperty + { + public static readonly string Id = $"{typeof(TestCaseMetaDataProperty).FullName}"; + public const string Label = "Test case meta data"; + + public int NrOfTestCasesInSuite { get; } + public int NrOfTestCasesInExecutable { get; } + + public TestCaseMetaDataProperty(int nrOfTestCasesInSuite, int nrOfTestCasesInExecutable) + : this($"{nrOfTestCasesInSuite}:{nrOfTestCasesInExecutable}") + { + } + + public TestCaseMetaDataProperty(string serialization) : base(serialization) + { + int[] values = serialization.Split(':').Select(int.Parse).ToArray(); + if (values.Length != 2) + throw new ArgumentException(serialization, nameof(serialization)); + NrOfTestCasesInSuite = values[0]; + NrOfTestCasesInExecutable = values[1]; + } + } +} \ No newline at end of file diff --git a/GoogleTestAdapter/Core/Model/TestProperty.cs b/GoogleTestAdapter/Core/Model/TestProperty.cs new file mode 100644 index 000000000..f00d98cb7 --- /dev/null +++ b/GoogleTestAdapter/Core/Model/TestProperty.cs @@ -0,0 +1,35 @@ +namespace GoogleTestAdapter.Model +{ + public abstract class TestProperty + { + public string Serialization { get; } + + protected TestProperty(string serialization) + { + Serialization = serialization; + } + + public override string ToString() + { + return $"{GetType()}: {Serialization}"; + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + return false; + if (ReferenceEquals(this, obj)) + return true; + if (obj.GetType() != GetType()) + return false; + + var other = (TestProperty) obj; + return string.Equals(Serialization, other.Serialization); + } + + public override int GetHashCode() + { + return Serialization != null ? Serialization.GetHashCode() : 0; + } + } +} \ No newline at end of file diff --git a/GoogleTestAdapter/Core/Runners/CommandLineGenerator.cs b/GoogleTestAdapter/Core/Runners/CommandLineGenerator.cs index b7f1cf1bd..4623a4562 100644 --- a/GoogleTestAdapter/Core/Runners/CommandLineGenerator.cs +++ b/GoogleTestAdapter/Core/Runners/CommandLineGenerator.cs @@ -12,10 +12,10 @@ public class CommandLineGenerator { public class Args { - public List TestCases { get; } + public IList TestCases { get; } public string CommandLine { get; } - internal Args(List testCases, string commandLine) + internal Args(IList testCases, string commandLine) { TestCases = testCases ?? new List(); CommandLine = commandLine ?? ""; @@ -26,14 +26,12 @@ internal Args(List testCases, string commandLine) public const int MaxCommandLength = 8191; private readonly int _lengthOfExecutableString; - private readonly IEnumerable _allTestCases; - private readonly IEnumerable _testCasesToRun; + private readonly IList _testCasesToRun; private readonly string _resultXmlFile; private readonly SettingsWrapper _settings; private readonly string _userParameters; - public CommandLineGenerator( - IEnumerable allTestCases, IEnumerable testCasesToRun, + public CommandLineGenerator(IEnumerable testCasesToRun, int lengthOfExecutableString, string userParameters, string resultXmlFile, SettingsWrapper settings) { @@ -41,8 +39,7 @@ public CommandLineGenerator( throw new ArgumentNullException(nameof(userParameters)); _lengthOfExecutableString = lengthOfExecutableString; - _allTestCases = allTestCases; - _testCasesToRun = testCasesToRun; + _testCasesToRun = testCasesToRun.ToList(); _resultXmlFile = resultXmlFile; _settings = settings; _userParameters = userParameters; @@ -68,7 +65,7 @@ private IEnumerable GetFinalCommandLines(string baseCommandLine) string userParam = GetAdditionalUserParameter(); if (AllTestCasesOfExecutableAreRun()) { - commandLines.Add(new Args(_testCasesToRun.ToList(), baseCommandLine + userParam)); + commandLines.Add(new Args(_testCasesToRun, baseCommandLine + userParam)); return commandLines; } @@ -81,7 +78,7 @@ private IEnumerable GetFinalCommandLines(string baseCommandLine) List testCasesRunBySuite = _testCasesToRun.Where(tc => !testCasesNotRunBySuite.Contains(tc)).ToList(); if (testCasesNotRunBySuite.Count == 0) { - commandLines.Add(new Args(_testCasesToRun.ToList(), baseCommandLineWithFilter + userParam)); + commandLines.Add(new Args(_testCasesToRun, baseCommandLineWithFilter + userParam)); return commandLines; } @@ -199,9 +196,16 @@ private string GetFilterForSuitesRunningAllTests(List suitesRunningAllTe private bool AllTestCasesOfExecutableAreRun() { - var allTestCasesAsSet = new HashSet(_allTestCases); - var testCasesToRunAsSet = new HashSet(_testCasesToRun); - return allTestCasesAsSet.SetEquals(testCasesToRunAsSet); + if (!_testCasesToRun.Any()) + return true; + + TestCaseMetaDataProperty metaData = _testCasesToRun.First().Properties + .OfType() + .SingleOrDefault(); + if (metaData == null) + throw new Exception($"Test does not have meta data: {_testCasesToRun.First()}"); + + return _testCasesToRun.Count == metaData.NrOfTestCasesInExecutable; } private List GetTestCasesNotRunBySuite(List suitesRunningAllTests) @@ -226,11 +230,14 @@ private List GetSuitesRunningAllTests() foreach (string suite in GetAllSuitesOfTestCasesToRun()) { List allMatchingTestCasesToBeRun = GetAllMatchingTestCases(_testCasesToRun, suite); - List allMatchingTestCases = GetAllMatchingTestCases(_allTestCases, suite); - if (allMatchingTestCasesToBeRun.Count == allMatchingTestCases.Count) - { + TestCaseMetaDataProperty metaData = allMatchingTestCasesToBeRun.First().Properties + .OfType() + .SingleOrDefault(); + if (metaData == null) + throw new Exception($"Test does not have meta data: {allMatchingTestCasesToBeRun.First()}"); + + if (allMatchingTestCasesToBeRun.Count == metaData.NrOfTestCasesInSuite) suitesRunningAllTests.Add(suite); - } } return suitesRunningAllTests; } diff --git a/GoogleTestAdapter/Core/Runners/ITestRunner.cs b/GoogleTestAdapter/Core/Runners/ITestRunner.cs index b49910d67..9f5a01ec5 100644 --- a/GoogleTestAdapter/Core/Runners/ITestRunner.cs +++ b/GoogleTestAdapter/Core/Runners/ITestRunner.cs @@ -8,7 +8,7 @@ namespace GoogleTestAdapter.Runners public interface ITestRunner { // TODO remove isBeingDebugged parameter (use debuggedLauncher != null) - void RunTests(IEnumerable allTestCases, IEnumerable testCasesToRun, string baseDir, string workingDir, + void RunTests(IEnumerable testCasesToRun, string baseDir, string workingDir, string userParameters, bool isBeingDebugged, IDebuggedProcessLauncher debuggedLauncher, IProcessExecutor executor); void Cancel(); diff --git a/GoogleTestAdapter/Core/Runners/ParallelTestRunner.cs b/GoogleTestAdapter/Core/Runners/ParallelTestRunner.cs index ae37be2e8..93f933cee 100644 --- a/GoogleTestAdapter/Core/Runners/ParallelTestRunner.cs +++ b/GoogleTestAdapter/Core/Runners/ParallelTestRunner.cs @@ -30,7 +30,7 @@ public ParallelTestRunner(ITestFrameworkReporter reporter, ILogger logger, Setti } - public void RunTests(IEnumerable allTestCases, IEnumerable testCasesToRun, string baseDir, + public void RunTests(IEnumerable testCasesToRun, string baseDir, string workingDir, string userParameters, bool isBeingDebugged, IDebuggedProcessLauncher debuggedLauncher, IProcessExecutor executor) { List threads; @@ -40,7 +40,7 @@ public void RunTests(IEnumerable allTestCases, IEnumerable t DebugUtils.AssertIsNull(userParameters, nameof(userParameters)); threads = new List(); - RunTests(allTestCases, testCasesToRun, baseDir, threads, isBeingDebugged, debuggedLauncher, executor); + RunTests(testCasesToRun, baseDir, threads, isBeingDebugged, debuggedLauncher, executor); } foreach (Thread thread in threads) @@ -61,7 +61,7 @@ public void Cancel() } - private void RunTests(IEnumerable allTestCases, IEnumerable testCasesToRun, string baseDir, List threads, bool isBeingDebugged, IDebuggedProcessLauncher debuggedLauncher, IProcessExecutor executor) + private void RunTests(IEnumerable testCasesToRun, string baseDir, List threads, bool isBeingDebugged, IDebuggedProcessLauncher debuggedLauncher, IProcessExecutor executor) { TestCase[] testCasesToRunAsArray = testCasesToRun as TestCase[] ?? testCasesToRun.ToArray(); @@ -78,7 +78,7 @@ private void RunTests(IEnumerable allTestCases, IEnumerable _testRunners.Add(runner); var thread = new Thread( - () => runner.RunTests(allTestCases, testcases, baseDir, null, null, isBeingDebugged, debuggedLauncher, executor)){ Name = $"GTA Testrunner {threadId}" }; + () => runner.RunTests(testcases, baseDir, null, null, isBeingDebugged, debuggedLauncher, executor)){ Name = $"GTA Testrunner {threadId}" }; threads.Add(thread); thread.Start(); diff --git a/GoogleTestAdapter/Core/Runners/PreparingTestRunner.cs b/GoogleTestAdapter/Core/Runners/PreparingTestRunner.cs index de4ea495f..cfe469099 100644 --- a/GoogleTestAdapter/Core/Runners/PreparingTestRunner.cs +++ b/GoogleTestAdapter/Core/Runners/PreparingTestRunner.cs @@ -41,7 +41,7 @@ public PreparingTestRunner(string solutionDirectory, ITestFrameworkReporter repo } - public void RunTests(IEnumerable allTestCases, IEnumerable testCasesToRun, string baseDir, + public void RunTests(IEnumerable testCasesToRun, string baseDir, string workingDir, string userParameters, bool isBeingDebugged, IDebuggedProcessLauncher debuggedLauncher, IProcessExecutor executor) { DebugUtils.AssertIsNull(userParameters, nameof(userParameters)); @@ -59,7 +59,7 @@ public void RunTests(IEnumerable allTestCases, IEnumerable t batch = batch == "" ? "" : _solutionDirectory + batch; SafeRunBatch(TestSetup, _solutionDirectory, batch, isBeingDebugged); - _innerTestRunner.RunTests(allTestCases, testCasesToRun, baseDir, workingDir, userParameters, isBeingDebugged, debuggedLauncher, executor); + _innerTestRunner.RunTests(testCasesToRun, baseDir, workingDir, userParameters, isBeingDebugged, debuggedLauncher, executor); batch = _settings.GetBatchForTestTeardown(_solutionDirectory, testDirectory, _threadId); batch = batch == "" ? "" : _solutionDirectory + batch; diff --git a/GoogleTestAdapter/Core/Runners/SequentialTestRunner.cs b/GoogleTestAdapter/Core/Runners/SequentialTestRunner.cs index 04b86a6b5..57f8a7f27 100644 --- a/GoogleTestAdapter/Core/Runners/SequentialTestRunner.cs +++ b/GoogleTestAdapter/Core/Runners/SequentialTestRunner.cs @@ -34,14 +34,13 @@ public SequentialTestRunner(string threadName, ITestFrameworkReporter reporter, } - public void RunTests(IEnumerable allTestCases, IEnumerable testCasesToRun, string baseDir, + public void RunTests(IEnumerable testCasesToRun, string baseDir, string workingDir, string userParameters, bool isBeingDebugged, IDebuggedProcessLauncher debuggedLauncher, IProcessExecutor executor) { DebugUtils.AssertIsNotNull(userParameters, nameof(userParameters)); DebugUtils.AssertIsNotNull(workingDir, nameof(workingDir)); IDictionary> groupedTestCases = testCasesToRun.GroupByExecutable(); - TestCase[] allTestCasesAsArray = allTestCases as TestCase[] ?? allTestCases.ToArray(); foreach (string executable in groupedTestCases.Keys) { string finalParameters = SettingsWrapper.ReplacePlaceholders(userParameters, executable); @@ -55,9 +54,7 @@ public void RunTests(IEnumerable allTestCases, IEnumerable t RunTestsFromExecutable( executable, finalWorkingDir, - allTestCasesAsArray.Where(tc => tc.Source == executable), groupedTestCases[executable], - baseDir, finalParameters, isBeingDebugged, debuggedLauncher, @@ -80,13 +77,13 @@ public void Cancel() // ReSharper disable once UnusedParameter.Local private void RunTestsFromExecutable(string executable, string workingDir, - IEnumerable allTestCases, IEnumerable testCasesToRun, string baseDir, string userParameters, + IEnumerable testCasesToRun, string userParameters, bool isBeingDebugged, IDebuggedProcessLauncher debuggedLauncher, IProcessExecutor executor) { string resultXmlFile = Path.GetTempFileName(); var serializer = new TestDurationSerializer(); - var generator = new CommandLineGenerator(allTestCases, testCasesToRun, executable.Length, userParameters, resultXmlFile, _settings); + var generator = new CommandLineGenerator(testCasesToRun, executable.Length, userParameters, resultXmlFile, _settings); foreach (CommandLineGenerator.Args arguments in generator.GetCommandLines()) { if (_canceled) diff --git a/GoogleTestAdapter/Core/TestCases/TestCaseFactory.cs b/GoogleTestAdapter/Core/TestCases/TestCaseFactory.cs index 3396e110f..fde1c4dc4 100644 --- a/GoogleTestAdapter/Core/TestCases/TestCaseFactory.cs +++ b/GoogleTestAdapter/Core/TestCases/TestCaseFactory.cs @@ -57,13 +57,31 @@ public IList CreateTestCases(Action reportTestCase = null) } IList testCaseDescriptors = new ListTestsParser(_settings.TestNameSeparator).ParseListTestsOutput(standardOutput); - if (_settings.ParseSymbolInformation) + List testCaseLocations = GetTestCaseLocations(testCaseDescriptors, _settings.GetPathExtension(_executable)); + + IList testCases = new List(); + IDictionary> suite2TestCases = new Dictionary>(); + foreach (var descriptor in testCaseDescriptors) + { + var testCase = _settings.ParseSymbolInformation + ? CreateTestCase(descriptor, testCaseLocations) + : CreateTestCase(descriptor); + ISet testCasesInSuite; + if (!suite2TestCases.TryGetValue(descriptor.Suite, out testCasesInSuite)) + suite2TestCases.Add(descriptor.Suite, testCasesInSuite = new HashSet()); + testCasesInSuite.Add(testCase); + testCases.Add(testCase); + } + + foreach (var suiteTestCasesPair in suite2TestCases) { - List testCaseLocations = GetTestCaseLocations(testCaseDescriptors, _settings.GetPathExtension(_executable)); - return testCaseDescriptors.Select(descriptor => CreateTestCase(descriptor, testCaseLocations)).ToList(); + foreach (var testCase in suiteTestCasesPair.Value) + { + testCase.Properties.Add(new TestCaseMetaDataProperty(suiteTestCasesPair.Value.Count, testCases.Count)); + } } - return testCaseDescriptors.Select(CreateTestCase).ToList(); + return testCases; } private IList NewCreateTestcases(Action reportTestCase, List standardOutput) @@ -77,6 +95,7 @@ private IList NewCreateTestcases(Action reportTestCase, List _settings.ParseSymbolInformation, _logger); + var suite2TestCases = new Dictionary>(); var parser = new StreamingListTestsParser(_settings.TestNameSeparator); parser.TestCaseDescriptorCreated += (sender, args) => { @@ -92,8 +111,12 @@ private IList NewCreateTestcases(Action reportTestCase, List { testCase = CreateTestCase(args.TestCaseDescriptor); } - reportTestCase?.Invoke(testCase); testCases.Add(testCase); + + ISet testCasesOfSuite; + if (!suite2TestCases.TryGetValue(args.TestCaseDescriptor.Suite, out testCasesOfSuite)) + suite2TestCases.Add(args.TestCaseDescriptor.Suite, testCasesOfSuite = new HashSet()); + testCasesOfSuite.Add(testCase); }; Action lineAction = s => @@ -133,6 +156,15 @@ private IList NewCreateTestcases(Action reportTestCase, List return new List(); } + foreach (var suiteTestCasesPair in suite2TestCases) + { + foreach (var testCase in suiteTestCasesPair.Value) + { + testCase.Properties.Add(new TestCaseMetaDataProperty(suiteTestCasesPair.Value.Count, testCases.Count)); + reportTestCase?.Invoke(testCase); + } + } + if (!CheckProcessExitCode(processExitCode, standardOutput)) return new List(); } diff --git a/GoogleTestAdapter/TestAdapter/DataConversionExtensions.cs b/GoogleTestAdapter/TestAdapter/DataConversionExtensions.cs index d5a99988f..661b1f504 100644 --- a/GoogleTestAdapter/TestAdapter/DataConversionExtensions.cs +++ b/GoogleTestAdapter/TestAdapter/DataConversionExtensions.cs @@ -3,7 +3,12 @@ using GoogleTestAdapter.Common; using GoogleTestAdapter.Model; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; +using TestCase = GoogleTestAdapter.Model.TestCase; +using TestOutcome = GoogleTestAdapter.Model.TestOutcome; +using TestResult = GoogleTestAdapter.Model.TestResult; +using Trait = GoogleTestAdapter.Model.Trait; using VsTestCase = Microsoft.VisualStudio.TestPlatform.ObjectModel.TestCase; +using VsTestProperty = Microsoft.VisualStudio.TestPlatform.ObjectModel.TestProperty; using VsTestResult = Microsoft.VisualStudio.TestPlatform.ObjectModel.TestResult; using VsTestOutcome = Microsoft.VisualStudio.TestPlatform.ObjectModel.TestOutcome; using VsTrait = Microsoft.VisualStudio.TestPlatform.ObjectModel.Trait; @@ -13,12 +18,24 @@ namespace GoogleTestAdapter.TestAdapter public static class DataConversionExtensions { + private static readonly VsTestProperty TestMetaDataProperty; + + static DataConversionExtensions() + { + TestMetaDataProperty = VsTestProperty.Register(TestCaseMetaDataProperty.Id, TestCaseMetaDataProperty.Label, typeof(string), typeof(VsTestCase)); + } + public static TestCase ToTestCase(this VsTestCase vsTestCase) { var testCase = new TestCase(vsTestCase.FullyQualifiedName, vsTestCase.Source, vsTestCase.DisplayName, vsTestCase.CodeFilePath, vsTestCase.LineNumber); testCase.Traits.AddRange(vsTestCase.Traits.Select(ToTrait)); + + var metaDataSerialization = vsTestCase.GetPropertyValue(TestMetaDataProperty); + if (metaDataSerialization != null) + testCase.Properties.Add(new TestCaseMetaDataProperty((string)metaDataSerialization)); + return testCase; } @@ -30,7 +47,13 @@ public static VsTestCase ToVsTestCase(this TestCase testCase) CodeFilePath = testCase.CodeFilePath, LineNumber = testCase.LineNumber }; + vsTestCase.Traits.AddRange(testCase.Traits.Select(ToVsTrait)); + + var property = testCase.Properties.OfType().SingleOrDefault(); + if (property != null) + vsTestCase.SetPropertyValue(TestMetaDataProperty, property.Serialization); + return vsTestCase; } diff --git a/GoogleTestAdapter/TestAdapter/TestExecutor.cs b/GoogleTestAdapter/TestAdapter/TestExecutor.cs index fe3ab5550..ae3f15d59 100644 --- a/GoogleTestAdapter/TestAdapter/TestExecutor.cs +++ b/GoogleTestAdapter/TestAdapter/TestExecutor.cs @@ -9,7 +9,6 @@ using GoogleTestAdapter.Helpers; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; -using GoogleTestAdapter.Helpers; using GoogleTestAdapter.Settings; using GoogleTestAdapter.Model; using GoogleTestAdapter.TestAdapter.Helpers; @@ -97,7 +96,7 @@ private void TryRunTests(IEnumerable executables, IRunContext runContext allTestCasesInExecutables.Where( tc => vsTestCasesToRun.Any(vtc => tc.FullyQualifiedName == vtc.FullyQualifiedName)).ToArray(); - DoRunTests(allTestCasesInExecutables, testCasesToRun, runContext, frameworkHandle); + DoRunTests(testCasesToRun, runContext, frameworkHandle); stopwatch.Stop(); _logger.LogInfo($"Google Test execution completed, overall duration: {stopwatch.Elapsed}."); @@ -112,11 +111,8 @@ private void TryRunTests(IEnumerable vsTestCasesToRun, IRunContext r var filter = new TestCaseFilter(runContext, allTraitNames, _logger); vsTestCasesToRun = filter.Filter(vsTestCasesToRunAsArray); - IEnumerable allTestCasesInExecutables = - GetAllTestCasesInExecutables(vsTestCasesToRun.Select(tc => tc.Source).Distinct()); - ICollection testCasesToRun = vsTestCasesToRun.Select(tc => tc.ToTestCase()).ToArray(); - DoRunTests(allTestCasesInExecutables, testCasesToRun, runContext, frameworkHandle); + DoRunTests(testCasesToRun, runContext, frameworkHandle); stopwatch.Stop(); _logger.LogInfo($"Google Test execution completed, overall duration: {stopwatch.Elapsed}."); @@ -183,9 +179,7 @@ private ISet GetAllTraitNames(IEnumerable testCases) return allTraitNames; } - private void DoRunTests( - IEnumerable allTestCasesInExecutables, ICollection testCasesToRun, - IRunContext runContext, IFrameworkHandle frameworkHandle) + private void DoRunTests(ICollection testCasesToRun, IRunContext runContext, IFrameworkHandle frameworkHandle) { bool isRunningInsideVisualStudio = !string.IsNullOrEmpty(runContext.SolutionDirectory); var reporter = new VsTestFrameworkReporter(frameworkHandle, isRunningInsideVisualStudio, _logger); @@ -205,7 +199,7 @@ private void DoRunTests( _executor = new GoogleTestExecutor(_logger, _settings); } - _executor.RunTests(allTestCasesInExecutables, testCasesToRun, reporter, launcher, + _executor.RunTests(testCasesToRun, reporter, launcher, runContext.IsBeingDebugged, runContext.SolutionDirectory, processExecutor); reporter.AllTestsFinished(); } diff --git a/GoogleTestAdapter/Tests.Common/TestDataCreator.cs b/GoogleTestAdapter/Tests.Common/TestDataCreator.cs index 30ec47e55..581590501 100644 --- a/GoogleTestAdapter/Tests.Common/TestDataCreator.cs +++ b/GoogleTestAdapter/Tests.Common/TestDataCreator.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using GoogleTestAdapter.Helpers; using GoogleTestAdapter.Model; using GoogleTestAdapter.Tests.Common.Helpers; @@ -86,9 +85,40 @@ public TestResult ToTestResult(string qualifiedTestCaseName, TestOutcome outcome }; } + public IEnumerable CreateDummyTestCasesFull(string[] qualifiedNamesToRun, string[] allQualifiedNames) + { + IDictionary> suite2TestCases = new Dictionary>(); + foreach (string qualifiedName in allQualifiedNames) + { + TestCase testCase = ToTestCase(qualifiedName); + + int index = qualifiedName.LastIndexOf(".", StringComparison.Ordinal); + string suite = qualifiedName.Substring(0, index); + ISet testCasesWithSuiteName; + if (!suite2TestCases.TryGetValue(suite, out testCasesWithSuiteName)) + suite2TestCases.Add(suite, testCasesWithSuiteName = new HashSet()); + testCasesWithSuiteName.Add(testCase); + } + + var testCases = new List(); + foreach (var suiteTestCasePair in suite2TestCases) + { + foreach (var testCase in suiteTestCasePair.Value) + { + if (qualifiedNamesToRun.Contains(testCase.FullyQualifiedName)) + { + testCase.Properties.Add(new TestCaseMetaDataProperty(suiteTestCasePair.Value.Count, allQualifiedNames.Length)); + testCases.Add(testCase); + } + } + } + + return testCases; + } + public IEnumerable CreateDummyTestCases(params string[] qualifiedNames) { - return qualifiedNames.Select(ToTestCase).ToList(); + return CreateDummyTestCasesFull(qualifiedNames, qualifiedNames); } }