From f40848574bcd0ea5431c6ba6b5d43a2683a74689 Mon Sep 17 00:00:00 2001 From: Andreas Willich Date: Tue, 4 Jun 2019 16:45:34 +0200 Subject: [PATCH] RuntimePlugin Locator looks into TestAssembly folder (#1597) * as on .NET Core the SpecFlow.dll is not in the output folder and current directory is set to the TestResults folder, we have to search for runtime plugins in the test assembly folder * fix unit tests --- TechTalk.SpecFlow/Infrastructure/ContainerBuilder.cs | 12 +++++++----- TechTalk.SpecFlow/Plugins/IRuntimePluginLocator.cs | 1 + TechTalk.SpecFlow/Plugins/RuntimePluginLocator.cs | 10 +++++++++- TechTalk.SpecFlow/TestRunnerManager.cs | 2 +- .../Infrastructure/PluginTests.cs | 1 + .../Infrastructure/TestThreadContextTests.cs | 2 +- .../TestObjectFactories.cs | 2 +- .../TestRunnerManagerTest.cs | 2 +- 8 files changed, 22 insertions(+), 10 deletions(-) diff --git a/TechTalk.SpecFlow/Infrastructure/ContainerBuilder.cs b/TechTalk.SpecFlow/Infrastructure/ContainerBuilder.cs index 190d77eb4..6bcbc0e64 100644 --- a/TechTalk.SpecFlow/Infrastructure/ContainerBuilder.cs +++ b/TechTalk.SpecFlow/Infrastructure/ContainerBuilder.cs @@ -1,6 +1,8 @@ using BoDi; using System; using System.Collections.Generic; +using System.IO; +using System.Reflection; using TechTalk.SpecFlow.Configuration; using TechTalk.SpecFlow.Plugins; using TechTalk.SpecFlow.Tracing; @@ -10,7 +12,7 @@ namespace TechTalk.SpecFlow.Infrastructure { public interface IContainerBuilder { - IObjectContainer CreateGlobalContainer(IRuntimeConfigurationProvider configurationProvider = null); + IObjectContainer CreateGlobalContainer(Assembly testAssembly, IRuntimeConfigurationProvider configurationProvider = null); IObjectContainer CreateTestThreadContainer(IObjectContainer globalContainer); IObjectContainer CreateScenarioContainer(IObjectContainer testThreadContainer, ScenarioInfo scenarioInfo); IObjectContainer CreateFeatureContainer(IObjectContainer testThreadContainer, FeatureInfo featureInfo); @@ -27,7 +29,7 @@ public ContainerBuilder(IDefaultDependencyProvider defaultDependencyProvider = n _defaultDependencyProvider = defaultDependencyProvider ?? DefaultDependencyProvider; } - public virtual IObjectContainer CreateGlobalContainer(IRuntimeConfigurationProvider configurationProvider = null) + public virtual IObjectContainer CreateGlobalContainer(Assembly testAssembly, IRuntimeConfigurationProvider configurationProvider = null) { var container = new ObjectContainer(); container.RegisterInstanceAs(this); @@ -52,7 +54,7 @@ public virtual IObjectContainer CreateGlobalContainer(IRuntimeConfigurationProvi var unitTestProviderConfigration = container.Resolve(); - LoadPlugins(configurationProvider, container, runtimePluginEvents, specFlowConfiguration, unitTestProviderConfigration); + LoadPlugins(configurationProvider, container, runtimePluginEvents, specFlowConfiguration, unitTestProviderConfigration, testAssembly); runtimePluginEvents.RaiseConfigurationDefaults(specFlowConfiguration); @@ -126,7 +128,7 @@ public IObjectContainer CreateFeatureContainer(IObjectContainer testThreadContai } protected virtual void LoadPlugins(IRuntimeConfigurationProvider configurationProvider, ObjectContainer container, RuntimePluginEvents runtimePluginEvents, - SpecFlowConfiguration specFlowConfiguration, UnitTestProviderConfiguration unitTestProviderConfigration) + SpecFlowConfiguration specFlowConfiguration, UnitTestProviderConfiguration unitTestProviderConfigration, Assembly testAssembly) { // initialize plugins that were registered from code foreach (var runtimePlugin in container.Resolve>().Values) @@ -139,7 +141,7 @@ public IObjectContainer CreateFeatureContainer(IObjectContainer testThreadContai var pluginLocator = container.Resolve(); var pluginLoader = container.Resolve(); var traceListener = container.Resolve(); - foreach (var pluginPath in pluginLocator.GetAllRuntimePlugins()) + foreach (var pluginPath in pluginLocator.GetAllRuntimePlugins(Path.GetDirectoryName(testAssembly?.Location))) { LoadPlugin(pluginPath, pluginLoader, runtimePluginEvents, unitTestProviderConfigration, traceListener); } diff --git a/TechTalk.SpecFlow/Plugins/IRuntimePluginLocator.cs b/TechTalk.SpecFlow/Plugins/IRuntimePluginLocator.cs index bf8425794..a57126ef0 100644 --- a/TechTalk.SpecFlow/Plugins/IRuntimePluginLocator.cs +++ b/TechTalk.SpecFlow/Plugins/IRuntimePluginLocator.cs @@ -8,5 +8,6 @@ namespace TechTalk.SpecFlow.Plugins public interface IRuntimePluginLocator { IReadOnlyList GetAllRuntimePlugins(); + IReadOnlyList GetAllRuntimePlugins(string testAssemblyLocation); } } diff --git a/TechTalk.SpecFlow/Plugins/RuntimePluginLocator.cs b/TechTalk.SpecFlow/Plugins/RuntimePluginLocator.cs index 81d044abb..a49a6d9d2 100644 --- a/TechTalk.SpecFlow/Plugins/RuntimePluginLocator.cs +++ b/TechTalk.SpecFlow/Plugins/RuntimePluginLocator.cs @@ -17,13 +17,21 @@ public RuntimePluginLocator(IRuntimePluginLocationMerger runtimePluginLocationMe } public IReadOnlyList GetAllRuntimePlugins() + { + return GetAllRuntimePlugins(null); + } + + public IReadOnlyList GetAllRuntimePlugins(string testAssemblyLocation) { var allRuntimePlugins = new List(); allRuntimePlugins.AddRange(SearchPluginsInFolder(Environment.CurrentDirectory)); allRuntimePlugins.AddRange(SearchPluginsInFolder(_pathToFolderWithSpecFlowAssembly)); - + if (testAssemblyLocation.IsNotNullOrWhiteSpace()) + { + allRuntimePlugins.AddRange(SearchPluginsInFolder(testAssemblyLocation)); + } return _runtimePluginLocationMerger.Merge(allRuntimePlugins.Distinct().ToList()); } diff --git a/TechTalk.SpecFlow/TestRunnerManager.cs b/TechTalk.SpecFlow/TestRunnerManager.cs index 427d3a9db..de76168dd 100644 --- a/TechTalk.SpecFlow/TestRunnerManager.cs +++ b/TechTalk.SpecFlow/TestRunnerManager.cs @@ -204,7 +204,7 @@ private static ITestRunnerManager CreateTestRunnerManager(Assembly testAssembly, { containerBuilder = containerBuilder ?? new ContainerBuilder(); - var container = containerBuilder.CreateGlobalContainer(); + var container = containerBuilder.CreateGlobalContainer(testAssembly); var testRunnerManager = container.Resolve(); testRunnerManager.Initialize(testAssembly); return testRunnerManager; diff --git a/Tests/TechTalk.SpecFlow.RuntimeTests/Infrastructure/PluginTests.cs b/Tests/TechTalk.SpecFlow.RuntimeTests/Infrastructure/PluginTests.cs index d4438bb94..9daa4da2b 100644 --- a/Tests/TechTalk.SpecFlow.RuntimeTests/Infrastructure/PluginTests.cs +++ b/Tests/TechTalk.SpecFlow.RuntimeTests/Infrastructure/PluginTests.cs @@ -309,6 +309,7 @@ public override void RegisterGlobalContainerDefaults(BoDi.ObjectContainer contai var runtimePluginLocator = new Mock(); runtimePluginLocator.Setup(m => m.GetAllRuntimePlugins()).Returns(new List() { "aPlugin" }); + runtimePluginLocator.Setup(m => m.GetAllRuntimePlugins(It.IsAny())).Returns(new List() { "aPlugin" }); var pluginLoaderStub = new Mock(); diff --git a/Tests/TechTalk.SpecFlow.RuntimeTests/Infrastructure/TestThreadContextTests.cs b/Tests/TechTalk.SpecFlow.RuntimeTests/Infrastructure/TestThreadContextTests.cs index 0bb0af5ee..c6b159ce5 100644 --- a/Tests/TechTalk.SpecFlow.RuntimeTests/Infrastructure/TestThreadContextTests.cs +++ b/Tests/TechTalk.SpecFlow.RuntimeTests/Infrastructure/TestThreadContextTests.cs @@ -57,7 +57,7 @@ public void Should_be_able_to_resolve_from_scenario_container() // this basically tests the special registration in DefaultDependencyProvider var containerBuilder = new ContainerBuilder(); - var testThreadContainer = containerBuilder.CreateTestThreadContainer(containerBuilder.CreateGlobalContainer()); + var testThreadContainer = containerBuilder.CreateTestThreadContainer(containerBuilder.CreateGlobalContainer(typeof(TestThreadContextTests).Assembly)); var contextManager = CreateContextManager(testThreadContainer); contextManager.InitializeFeatureContext(new FeatureInfo(FeatureLanguage, "test feature", null)); contextManager.InitializeScenarioContext(new ScenarioInfo("test scenario", "test_description")); diff --git a/Tests/TechTalk.SpecFlow.RuntimeTests/TestObjectFactories.cs b/Tests/TechTalk.SpecFlow.RuntimeTests/TestObjectFactories.cs index 5f76e452e..8ac4f4b79 100644 --- a/Tests/TechTalk.SpecFlow.RuntimeTests/TestObjectFactories.cs +++ b/Tests/TechTalk.SpecFlow.RuntimeTests/TestObjectFactories.cs @@ -41,7 +41,7 @@ internal static IObjectContainer CreateDefaultFeatureContainer(StringConfigProvi private static IObjectContainer CreateDefaultGlobalContainer(IRuntimeConfigurationProvider configurationProvider, Action registerGlobalMocks, ContainerBuilder instance) { - var globalContainer = instance.CreateGlobalContainer(configurationProvider); + var globalContainer = instance.CreateGlobalContainer(typeof(TestObjectFactories).Assembly, configurationProvider); registerGlobalMocks?.Invoke(globalContainer); return globalContainer; } diff --git a/Tests/TechTalk.SpecFlow.RuntimeTests/TestRunnerManagerTest.cs b/Tests/TechTalk.SpecFlow.RuntimeTests/TestRunnerManagerTest.cs index c05dacc8f..c460d8d28 100644 --- a/Tests/TechTalk.SpecFlow.RuntimeTests/TestRunnerManagerTest.cs +++ b/Tests/TechTalk.SpecFlow.RuntimeTests/TestRunnerManagerTest.cs @@ -16,7 +16,7 @@ public class TestRunnerManagerTest public TestRunnerManagerTest() { - var globalContainer = new ContainerBuilder().CreateGlobalContainer(); + var globalContainer = new ContainerBuilder().CreateGlobalContainer(typeof(TestRunnerManagerTest).Assembly); testRunnerManager = globalContainer.Resolve(); testRunnerManager.Initialize(anAssembly); }