From 0124ddecae93acebe54f0a04593b82f1b5e02982 Mon Sep 17 00:00:00 2001 From: Vagisha Nidhi Date: Tue, 11 Jun 2019 13:38:52 +0530 Subject: [PATCH 1/2] Registrar Null Fixed --- .../RunSpecificTestsArgumentProcessor.cs | 56 ++++++++++++++++++- .../TestPlatformHelpers/TestRequestManager.cs | 2 +- .../FrameworkTests.cs | 24 ++++++++ 3 files changed, 80 insertions(+), 2 deletions(-) diff --git a/src/vstest.console/Processors/RunSpecificTestsArgumentProcessor.cs b/src/vstest.console/Processors/RunSpecificTestsArgumentProcessor.cs index c6350c762c..a0aa82b313 100644 --- a/src/vstest.console/Processors/RunSpecificTestsArgumentProcessor.cs +++ b/src/vstest.console/Processors/RunSpecificTestsArgumentProcessor.cs @@ -137,6 +137,11 @@ internal class RunSpecificTestsArgumentExecutor : IArgumentExecutor /// private ITestDiscoveryEventsRegistrar discoveryEventsRegistrar; + /// + /// Registers and Unregisters for test run events before and after test run + /// + private ITestRunEventsRegistrar testRunEventsRegistrar; + #endregion #region Constructor @@ -159,6 +164,7 @@ internal class RunSpecificTestsArgumentExecutor : IArgumentExecutor this.runSettingsManager = runSettingsProvider; this.output = output; this.discoveryEventsRegistrar = new DiscoveryEventsRegistrar(this.discoveryRequest_OnDiscoveredTests); + this.testRunEventsRegistrar = new TestRunRequestEventsRegistrar(this.output, this.commandLineOptions); } #endregion @@ -259,7 +265,7 @@ private void ExecuteSelectedTests() EqtTrace.Verbose("RunSpecificTestsArgumentProcessor:Execute: Test run is queued."); var runRequestPayload = new TestRunRequestPayload() { TestCases = this.selectedTestCases.ToList(), RunSettings = this.effectiveRunSettings, KeepAlive = keepAlive, TestPlatformOptions = new TestPlatformOptions() { TestCaseFilter = this.commandLineOptions.TestCaseFilterValue }}; - this.testRequestManager.RunTests(runRequestPayload, null, null, Constants.DefaultProtocolConfig); + this.testRequestManager.RunTests(runRequestPayload, null, this.testRunEventsRegistrar, Constants.DefaultProtocolConfig); } else { @@ -335,5 +341,53 @@ public void UnregisterDiscoveryEvents(IDiscoveryRequest discoveryRequest) discoveryRequest.OnDiscoveredTests -= this.discoveredTestsHandler; } } + + private class TestRunRequestEventsRegistrar : ITestRunEventsRegistrar + { + private IOutput output; + private CommandLineOptions commandLineOptions; + + public TestRunRequestEventsRegistrar(IOutput output, CommandLineOptions commandLineOptions) + { + this.output = output; + this.commandLineOptions = commandLineOptions; + } + + public void LogWarning(string message) + { + ConsoleLogger.RaiseTestRunWarning(message); + } + + public void RegisterTestRunEvents(ITestRunRequest testRunRequest) + { + testRunRequest.OnRunCompletion += TestRunRequest_OnRunCompletion; + } + + public void UnregisterTestRunEvents(ITestRunRequest testRunRequest) + { + testRunRequest.OnRunCompletion -= TestRunRequest_OnRunCompletion; + } + + /// + /// Handles the TestRunRequest complete event + /// + /// + /// RunCompletion args + private void TestRunRequest_OnRunCompletion(object sender, TestRunCompleteEventArgs e) + { + // If run is not aborted/cancelled then check the count of executed tests. + // we need to check if there are any tests executed - to try show some help info to user to check for installed vsix extensions + if (!e.IsAborted && !e.IsCanceled) + { + var testsFoundInAnySource = (e.TestRunStatistics == null) ? false : (e.TestRunStatistics.ExecutedTests > 0); + + // Indicate the user to use testadapterpath command if there are no tests found + if (!testsFoundInAnySource && string.IsNullOrEmpty(CommandLineOptions.Instance.TestAdapterPath) && this.commandLineOptions.TestCaseFilterValue == null) + { + this.output.Warning(false, CommandLineResources.SuggestTestAdapterPathIfNoTestsIsFound); + } + } + } + } } } \ No newline at end of file diff --git a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs index 1e8cd30055..109479fa63 100644 --- a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs +++ b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs @@ -435,7 +435,7 @@ private void CheckSourcesForCompatibility(Framework chosenFramework, Architectur if (!string.IsNullOrEmpty(incompatibleSettingWarning)) { EqtTrace.Warning(incompatibleSettingWarning); - registrar.LogWarning(incompatibleSettingWarning); + registrar?.LogWarning(incompatibleSettingWarning); } // Log compatible sources diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/FrameworkTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/FrameworkTests.cs index fd7dbb729a..2fa5b9823e 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/FrameworkTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/FrameworkTests.cs @@ -50,5 +50,29 @@ public void OnWrongFrameworkPassedTestRunShouldNotRun(RunnerInfo runnerInfo) this.StdErrorContains("Test Run Aborted."); } } + + [TestMethod] + [NetFullTargetFrameworkDataSource] + [NetCoreTargetFrameworkDataSource] + public void RunSpecificTestsShouldWorkWithFrameworkInCompatibleWarning(RunnerInfo runnerInfo) + { + AcceptanceTestBase.SetTestEnvironment(this.testEnvironment, runnerInfo); + + var arguments = PrepareArguments(GetSampleTestAssembly(), string.Empty, string.Empty, this.FrameworkArgValue); + arguments = string.Concat(arguments, " ", "/tests:PassingTest"); + arguments = string.Concat(arguments, " ", "/Framework:Framework40"); + + this.InvokeVsTest(arguments); + + if (runnerInfo.TargetFramework.Contains("netcore")) + { + this.StdOutputContains("No test is available"); + } + else + { + this.StdOutputContains("Following DLL(s) do not match framework/platform settings. "); + this.ValidateSummaryStatus(1, 0, 0); + } + } } } \ No newline at end of file From 3ff3c6a2f298a86c701bf9250de7a1d18ef4e4f1 Mon Sep 17 00:00:00 2001 From: Vagisha Nidhi Date: Wed, 12 Jun 2019 10:31:30 +0530 Subject: [PATCH 2/2] Adding RunSpecific UTs --- .../RunSpecificTestsArgumentProcessorTests.cs | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/test/vstest.console.UnitTests/Processors/RunSpecificTestsArgumentProcessorTests.cs b/test/vstest.console.UnitTests/Processors/RunSpecificTestsArgumentProcessorTests.cs index fb417c54d4..a569d331c9 100644 --- a/test/vstest.console.UnitTests/Processors/RunSpecificTestsArgumentProcessorTests.cs +++ b/test/vstest.console.UnitTests/Processors/RunSpecificTestsArgumentProcessorTests.cs @@ -482,6 +482,64 @@ public void ExecutorShouldRunTestsWhenTestsAreCommaSeparatedWithEscape() Assert.AreEqual(ArgumentProcessorResult.Success, argumentProcessorResult); } + [TestMethod] + public void ExecutorShouldDisplayWarningIfNoTestsAreExecuted() + { + var mockTestPlatform = new Mock(); + var mockTestRunRequest = new Mock(); + var mockDiscoveryRequest = new Mock(); + var mockTestRunStats = new Mock(); + + List list = new List(); + list.Add(new TestCase("Test1", new Uri("http://FooTestUri1"), "Source1")); + list.Add(new TestCase("Test2", new Uri("http://FooTestUri2"), "Source2")); + mockDiscoveryRequest.Setup(dr => dr.DiscoverAsync()).Raises(dr => dr.OnDiscoveredTests += null, new DiscoveredTestsEventArgs(list)); + + mockTestRunRequest.Setup(tr => tr.ExecuteAsync()).Returns(1).Raises(tr => tr.OnRunCompletion += null, + new TestRunCompleteEventArgs(mockTestRunStats.Object, false, false, null, null, new TimeSpan())); + + mockTestPlatform.Setup(tp => tp.CreateTestRunRequest(It.IsAny(), It.IsAny(), It.IsAny())).Returns(mockTestRunRequest.Object); + mockTestPlatform.Setup(tp => tp.CreateDiscoveryRequest(It.IsAny(), It.IsAny(), It.IsAny())).Returns(mockDiscoveryRequest.Object); + + this.ResetAndAddSourceToCommandLineOptions(); + var testRequestManager = new TestRequestManager(CommandLineOptions.Instance, mockTestPlatform.Object, TestRunResultAggregator.Instance, this.mockTestPlatformEventSource.Object, this.inferHelper, this.mockMetricsPublisherTask); + var executor = GetExecutor(testRequestManager); + + executor.Initialize("Test1"); + executor.Execute(); + + this.mockOutput.Verify(op => op.WriteLine(It.Is(st => st.Contains("Additionally, path to test adapters can be specified using /TestAdapterPath command.")), OutputLevel.Warning), Times.Once); + } + + [TestMethod] + public void ExecutorShouldNotDisplayWarningIfTestsAreExecuted() + { + var mockTestPlatform = new Mock(); + var mockTestRunRequest = new Mock(); + var mockDiscoveryRequest = new Mock(); + var testRunStats = new TestRunStatistics(1, new Dictionary { { TestOutcome.Passed, 1 } }); + + List list = new List(); + list.Add(new TestCase("Test1", new Uri("http://FooTestUri1"), "Source1")); + list.Add(new TestCase("Test2", new Uri("http://FooTestUri2"), "Source2")); + mockDiscoveryRequest.Setup(dr => dr.DiscoverAsync()).Raises(dr => dr.OnDiscoveredTests += null, new DiscoveredTestsEventArgs(list)); + + mockTestRunRequest.Setup(tr => tr.ExecuteAsync()).Returns(1).Raises(tr => tr.OnRunCompletion += null, + new TestRunCompleteEventArgs(testRunStats, false, false, null, null, new TimeSpan())); + + mockTestPlatform.Setup(tp => tp.CreateTestRunRequest(It.IsAny(), It.IsAny(), It.IsAny())).Returns(mockTestRunRequest.Object); + mockTestPlatform.Setup(tp => tp.CreateDiscoveryRequest(It.IsAny(), It.IsAny(), It.IsAny())).Returns(mockDiscoveryRequest.Object); + + this.ResetAndAddSourceToCommandLineOptions(); + var testRequestManager = new TestRequestManager(CommandLineOptions.Instance, mockTestPlatform.Object, TestRunResultAggregator.Instance, this.mockTestPlatformEventSource.Object, this.inferHelper, this.mockMetricsPublisherTask); + var executor = GetExecutor(testRequestManager); + + executor.Initialize("Test1"); + executor.Execute(); + + this.mockOutput.Verify(op => op.WriteLine(It.Is(st => st.Contains("Additionally, path to test adapters can be specified using /TestAdapterPath command.")), OutputLevel.Warning), Times.Never); + } + #endregion private void ResetAndAddSourceToCommandLineOptions()