public void SetUp() { Builder = ScenarioMocks.CreateScenarioBuilder(); var configuration = TestableIntegrationContextBuilder.Default().Build().Configuration; Builder.SetupConfiguration(configuration); Runner = new MockBddRunner <T>(configuration, Builder.Object); }
private static Task RunScenarioAsync(IBddRunner runner) { return(runner.WithContext(new ExplicitContext()).RunScenarioAsync( ctx => ctx.Given_implicit_context_initialized(), ctx => ctx.When_time_elapsed_allowing_other_scenario_to_execute_concurrently(), ctx => ctx.Then_implicit_context_should_be_preserved(), ctx => ctx.Then_implicit_context_should_be_preserved_in_subtasks())); }
/// <summary> /// Specifies that scenario will be executed in dedicated context of <typeparamref name="TContext"/> type, created by <paramref name="contextFactory"/> function.<br/> /// The <paramref name="onConfigure"/> function can be used to configure the context after instantiation.<br/> /// The context instance will be created just before scenario execution.<br/> /// All context instances implementing <see cref="IDisposable"/> interface will be disposed after scenario execution. /// </summary> /// <typeparam name="TContext">Context type.</typeparam> /// <param name="runner"><see cref="IBddRunner"/> instance.</param> /// <param name="contextFactory">Context factory function.</param> /// <param name="onConfigure">Custom context configuration executed after context creation. Can be null.</param> /// <returns>Contextual runner.</returns> public static IBddRunner <TContext> WithContext <TContext>(this IBddRunner runner, Func <IDependencyResolver, TContext> contextFactory, Action <TContext> onConfigure = null) { return(new ContextualBddRunner <TContext>(runner, resolver => { var context = contextFactory.Invoke(resolver); onConfigure?.Invoke(context); return context; })); }
/// <summary> /// Specifies that scenario will be executed in dedicated context of <typeparamref name="TContext"/> type.<br/> /// The <paramref name="onConfigure"/> function can be used to configure the context after instantiation.<br/> /// The context instance will be created by calling default constructor just before scenario execution.<br/> /// All context instances implementing <see cref="IDisposable"/> interface will be disposed after scenario execution. /// </summary> /// <param name="runner"><see cref="IBddRunner"/> instance.</param> /// <typeparam name="TContext">Context type.</typeparam> /// <param name="onConfigure">Custom context configuration executed after context creation. Can be null.</param> /// <returns>Contextual runner.</returns> public static IBddRunner <TContext> WithContext <TContext>(this IBddRunner runner, Action <TContext> onConfigure) { return(new ContextualBddRunner <TContext>(runner, resolver => { var context = resolver.Resolve <TContext>(); onConfigure?.Invoke(context); return context; })); }
/// <summary> /// Runs test scenario by executing given steps in specified order.<br/> /// If given step throws, other are not executed.<br/> /// Scenario name is determined from the method name in which <see cref="RunScenarioAsync"/>() method is called.<br/> /// Scenario labels are determined from <see cref="LabelAttribute"/> attributes applied on scenario method.<br/> /// Step name is determined from corresponding action name.<br/> /// Example usage: /// <code> /// [Scenario] /// [Label("Ticket-1")] /// public Task Successful_login() /// { /// return Runner.RunScenarioAsync( /// Given_the_user_is_about_to_login, /// Given_the_user_entered_valid_login, /// Given_the_user_entered_valid_password, /// When_the_user_clicks_login_button, /// Then_the_login_operation_should_be_successful, /// Then_a_welcome_message_containing_user_name_should_be_returned); /// } /// </code> /// Expected step signature: /// <code> /// async Task Given_the_user_is_about_to_login() { /* ... */ } /// </code> /// </summary> /// <param name="runner">Runner.</param> /// <param name="steps">List of steps to execute in order.</param> public static async Task RunScenarioAsync(this IBddRunner runner, params Func <Task>[] steps) { try { await Basic(runner) .BuildAsyncScenario(steps) .RunScenarioAsync(); } catch (ScenarioExecutionException e) { e.GetOriginal().Throw(); } }
/// <summary> /// Runs test scenario by executing given steps in specified order.<br/> /// If given step throws, other are not executed.<br/> /// Scenario name is determined from the method name in which <see cref="RunScenarioActionsAsync{TContext}"/>() method was called.<br/> /// Scenario labels are determined from <see cref="LabelAttribute"/> attributes applied on method in which <see cref="RunScenarioActionsAsync{TContext}"/>() method was called.<br/> /// Step name is determined from lambda parameter name reflecting action type keyword, corresponding action name and passed list of parameters to called method.<br/> /// If scenario is executed with context, the context instance is provided with lambda parameter. /// Please note that rules for placing parameter values in step name are as follows, where first matching rule would be used: /// <list type="bullet"> /// <item><description>it will replace first occurrence of variable name written in capital letters (<c>void Price_is_AMOUNT_dollars(int amount)</c> => <c>Price is "27" dollars</c>)</description></item> /// <item><description>it will placed after first occurrence of variable name (<c>void Product_is_in_stock(string product)</c> => <c>Product "desk" is in stock</c>)</description></item> /// <item><description>it will placed at the end of step name (<c>void Product_is_in_stock(string productId)</c> => <c>Product is in stock [productId: "ABC123"]</c>)</description></item> /// </list> /// <para> /// Example usage for scenarios with no context: /// <code> /// [Scenario] /// [Label("Ticket-2")] /// public Task Receiving_invoice_for_products() /// { /// return Runner.RunScenarioActionsAsync( /// _ => Given_product_is_available_in_product_storage("wooden desk"), /// _ => Given_product_is_available_in_product_storage("wooden shelf"), /// _ => When_customer_buys_product("wooden desk"), /// _ => When_customer_buys_product("wooden shelf"), /// _ => Then_an_invoice_should_be_sent_to_the_customer(), /// _ => Then_invoice_should_contain_product_with_price_of_AMOUNT_pounds("wooden desk", 62), /// _ => Then_invoice_should_contain_product_with_price_of_AMOUNT_pounds("wooden shelf", 37)); /// } /// </code> /// Expected step signature: /// <code> /// async void Given_product_is_available_in_product_storage(string product) { /* ... */ } /// </code> /// or /// <code> /// void Given_product_is_available_in_product_storage(string product) { /* ... */ } /// </code> /// </para> /// <para> /// Example usage for scenarios with context: /// <code> /// [Scenario] /// [Label("Ticket-3")] /// public Task Should_dispatch_product_after_payment_is_finalized() /// { /// return Runner.WithContext<SpeditionContext>().RunScenarioActionsAsync( /// _ => _.Given_there_is_an_active_customer_with_id("ABC-123"), /// _ => _.Given_the_customer_has_product_in_basket("wooden shelf"), /// _ => _.Given_the_customer_has_product_in_basket("wooden desk"), /// _ => _.When_the_customer_payment_finalizes(), /// _ => _.Then_product_should_be_dispatched_to_the_customer("wooden shelf"), /// _ => _.Then_product_should_be_dispatched_to_the_customer("wooden desk")); /// } /// </code> /// Expected step signature: /// <code> /// class SpeditionContext /// { /// async void Given_product_is_available_in_product_storage(string product) { /* ... */ } /// } /// </code> /// or /// <code> /// class SpeditionContext /// { /// void Given_product_is_available_in_product_storage(string product) { /* ... */ } /// } /// </code> /// </para> /// </summary> /// <remarks>This is an asynchronous method and should be awaited.</remarks> /// <param name="runner">Runner.</param> /// <param name="steps">List of steps to execute in order.</param> public static async Task RunScenarioActionsAsync <TContext>(this IBddRunner <TContext> runner, params Expression <Action <TContext> >[] steps) { try { await AsExtended(runner) .BuildAsyncScenario(steps) .RunScenarioAsync(); } catch (ScenarioExecutionException e) { e.GetOriginal().Throw(); } }
/// <summary> /// Runs test scenario by executing given steps in specified order.<br/> /// If given step throws, other are not executed.<br/> /// Scenario name is determined from the method name in which <see cref="RunScenario"/>() method is called.<br/> /// Scenario labels are determined from <see cref="LabelAttribute"/> attributes applied on scenario method.<br/> /// Step name is determined from corresponding action name.<br/> /// Example usage: /// <code> /// [Scenario] /// [Label("Ticket-1")] /// public void Successful_login() /// { /// Runner.RunScenario( /// Given_the_user_is_about_to_login, /// Given_the_user_entered_valid_login, /// Given_the_user_entered_valid_password, /// When_the_user_clicks_login_button, /// Then_the_login_operation_should_be_successful, /// Then_a_welcome_message_containing_user_name_should_be_returned); /// } /// </code> /// Expected step signature: /// <code> /// void Given_the_user_is_about_to_login() { /* ... */ } /// </code> /// </summary> /// <param name="runner">Runner.</param> /// <param name="steps">List of steps to execute in order.</param> public static void RunScenario(this IBddRunner runner, params Action[] steps) { try { Basic(runner) .BuildScenario(steps) .RunScenario(); } catch (ScenarioExecutionException e) { e.GetOriginal().Throw(); } }
/// <summary> /// Runs test scenario by executing given steps in specified order.<br/> /// If given step throws, other are not executed.<br/> /// Scenario name is determined from the method name in which <see cref="RunScenario{TContext}"/>() method was called.<br/> /// Scenario labels are determined from <see cref="LabelAttribute"/> attributes applied on method in which <see cref="RunScenario{TContext}"/>() method was called.<br/> /// Step name is determined from lambda parameter name reflecting action type keyword, corresponding action name and passed list of parameters to called method.<br/> /// If scenario is executed with context, the context instance is provided with lambda parameter. /// Please note that rules for placing parameter values in step name are as follows, where first matching rule would be used: /// <list type="bullet"> /// <item><description>it will replace first occurrence of variable name written in capital letters (<c>void Price_is_AMOUNT_dollars(int amount)</c> => <c>Price is "27" dollars</c>)</description></item> /// <item><description>it will placed after first occurrence of variable name (<c>void Product_is_in_stock(string product)</c> => <c>Product "desk" is in stock</c>)</description></item> /// <item><description>it will placed at the end of step name (<c>void Product_is_in_stock(string productId)</c> => <c>Product is in stock [productId: "ABC123"]</c>)</description></item> /// </list> /// <para> /// Example usage for scenarios with no context: /// <code> /// [Scenario] /// [Label("Ticket-2")] /// public void Receiving_invoice_for_products() /// { /// Runner.RunScenario( /// _ => Given_product_is_available_in_product_storage("wooden desk"), /// _ => When_customer_buys_product("wooden desk"), /// _ => Then_invoice_should_contain_product_with_price_of_AMOUNT_pounds("wooden desk", 62)); /// } /// </code> /// Expected step signature: /// <code> /// void Given_product_is_available_in_product_storage(string product) { /* ... */ } /// </code> /// </para> /// <para> /// Example usage for scenarios with context: /// <code> /// [Scenario] /// [Label("Ticket-3")] /// public void Should_dispatch_product_after_payment_is_finalized() /// { /// Runner.WithContext<SpeditionContext>().RunScenario( /// _ => _.Given_there_is_an_active_customer_with_id("ABC-123"), /// _ => _.Given_the_customer_has_product_in_basket("wooden shelf"), /// _ => _.When_the_customer_payment_finalizes(), /// _ => _.Then_product_should_be_dispatched_to_the_customer("wooden shelf")); /// } /// </code> /// Expected step signature: /// <code> /// class SpeditionContext /// { /// void Given_product_is_available_in_product_storage(string product) { /* ... */ } /// } /// </code> /// </para> /// </summary> /// <param name="runner">Runner.</param> /// <param name="steps">List of steps to execute in order.</param> public static void RunScenario <TContext>(this IBddRunner <TContext> runner, params Expression <Action <TContext> >[] steps) { try { AsExtended(runner) .BuildScenario(steps) .RunScenario(); } catch (ScenarioExecutionException e) { e.GetOriginal().Throw(); } }
/// <summary> /// Method allowing to retrieve the <see cref="IFeatureFixtureRunner"/> instance allowing to define and execute scenarios. /// This method is dedicated for projects extending LightBDD with user friendly API for running scenarios - it should not be used directly by regular LightBDD users. /// </summary> /// <typeparam name="TContext">Bdd runner context type.</typeparam> /// <param name="runner">Bdd runner.</param> /// <returns>Instance of <see cref="IFeatureFixtureRunner"/>.</returns> /// <exception cref="NotSupportedException">Thrown if <paramref name="runner"/> does not implement <see cref="IFeatureFixtureRunner"/>.</exception> public static IFeatureFixtureRunner Integrate <TContext>(this IBddRunner <TContext> runner) { if (runner == null) { throw new ArgumentNullException(nameof(runner)); } if (!(runner is IFeatureFixtureRunner)) { throw new NotSupportedException($"The type '{runner.GetType().Name}' has to implement '{nameof(IFeatureFixtureRunner)}' interface to support integration."); } return((IFeatureFixtureRunner)runner); }
/// <summary> /// Runs test scenario by executing given steps in specified order.<br/> /// If given step throws, other are not executed.<br/> /// The scenario name is determined from the current scenario test method.<br/> /// Scenario labels are determined from <see cref="LabelAttribute"/> attributes applied on scenario method.<br/> /// The step name is determined from lambda parameter name reflecting action type keyword, corresponding action name and passed list of parameters to called method.<br/> /// If scenario is executed with context, the context instance is provided with lambda parameter.<br/> /// Example usage: /// <code> /// Runner.RunScenario( /// _ => Given_numbers(5, 8), /// _ => When_I_add_them(), /// _ => I_should_receive_number(13)) /// </code> /// Expected step signature: <code>void Given_numbers(params int[] numbers) { /* ... */ }</code> /// </summary> /// <param name="runner">Runner.</param> /// <param name="steps">List of steps to execute in order.</param> public static void RunScenario <TContext>(this IBddRunner <TContext> runner, params Expression <Action <TContext> >[] steps) { try { var scenario = runner .AddSteps(steps) .Integrate().Core .WithCapturedScenarioDetails() .Build(); scenario.ExecuteSync(); } catch (ScenarioExecutionException e) { e.GetOriginal().Throw(); } }
/// <summary> /// Runs asynchronous test scenario by executing given steps in specified order.<br/> /// If given step throws, other are not executed.<br/> /// The scenario name is determined from the current scenario test method.<br/> /// Scenario labels are determined from <see cref="LabelAttribute"/> attributes applied on scenario method.<br/> /// The step name is determined from lambda parameter name reflecting action type keyword, corresponding action name and passed list of parameters to called method.<br/> /// If scenario is executed with context, the context instance is provided with lambda parameter.<br/> /// Example usage: /// <code> /// await Runner.RunScenarioAsync( /// _ => Given_numbers(5, 8), /// _ => When_I_add_them(), /// _ => I_should_receive_number(13)) /// </code> /// Expected step signature: <code>Task Given_numbers(params int[] numbers) { /* ... */ }</code> /// </summary> /// <remarks>This is an asynchronous method and should be awaited.</remarks> /// <param name="runner">Runner.</param> /// <param name="steps">List of steps to execute in order.</param> public static async Task RunScenarioAsync <TContext>(this IBddRunner <TContext> runner, params Expression <Func <TContext, Task> >[] steps) { try { var scenario = runner .AddAsyncSteps(steps) .Integrate().Core .WithCapturedScenarioDetails() .Build(); await scenario.ExecuteAsync(); } catch (ScenarioExecutionException e) { e.GetOriginal().Throw(); } }
public void SetUp() { _containerScope = new Mock <IDependencyContainerV2>(); _scenarioScope = new Mock <IDependencyContainerV2>(); _stepScope = new Mock <IDependencyContainerV2>(); _containerScope.Setup(x => x.BeginScope(It.IsAny <LifetimeScope>(), It.IsAny <Action <ContainerConfigurator> >())) .Returns(_scenarioScope.Object); _scenarioScope.Setup(x => x.BeginScope(It.IsAny <LifetimeScope>(), It.IsAny <Action <ContainerConfigurator> >())) .Returns(_stepScope.Object); _feature = new TestableFeatureRunnerRepository(TestableIntegrationContextBuilder.Default() .WithConfiguration(c => c.DependencyContainerConfiguration().UseContainer(_containerScope.Object))) .GetRunnerFor(GetType()); _runner = _feature.GetBddRunner(this); }
/// <summary> /// Given Extention for IBddRunner /// </summary> /// <param name="runner">Test-Runner</param> /// <param name="given">Test-Func to be executed</param> /// <returns>Given-object</returns> public static IGiven <Func <Task> > Given(this IBddRunner runner, Func <Task> given) { return(new Scene <Func <Task> >(runner) .Given(given)); }
/// <summary> /// Specifies that scenario will be executed in dedicated context of <typeparamref name="TContext"/> type.<br/> /// The context instance will be created by calling default constructor just before scenario execution.<br/> /// All context instances implementing <see cref="IDisposable"/> interface will be disposed after scenario execution. /// </summary> /// <param name="runner"><see cref="IBddRunner"/> instance.</param> /// <typeparam name="TContext">Context type.</typeparam> /// <returns>Contextual runner.</returns> public static IBddRunner <TContext> WithContext <TContext>(this IBddRunner runner) { return(new ContextualBddRunner <TContext>(runner, resolver => resolver.Resolve(typeof(TContext)))); }
/// <summary> /// Specifies that scenario will be executed in dedicated <paramref name="context"/> of <typeparamref name="TContext"/> type.<br/> /// The <paramref name="takeOwnership"/> specifies if created context should be disposed (when implements <see cref="IDisposable"/> interface) by scenario runner. By default is it set to <c>false</c>.<br/> /// </summary> /// <typeparam name="TContext">Context type.</typeparam> /// <param name="runner"><see cref="IBddRunner"/> instance.</param> /// <param name="context">Context instance.</param> /// <param name="takeOwnership">Specifies if scenario runner should take ownership of the context instance. If set to true and context instance implements <see cref="IDisposable"/>, it will be disposed after scenario finish.</param> /// <returns>Contextual runner.</returns> public static IBddRunner <TContext> WithContext <TContext>(this IBddRunner runner, TContext context, bool takeOwnership = false) { return(new ContextualBddRunner <TContext>(runner, () => context, takeOwnership)); }
/// <summary> /// Given Extention for IBddRunner /// </summary> /// <param name="runner">Test-Runner</param> /// <param name="given">Test-Action to be executed</param> /// <returns>Given-object</returns> public static IGiven <Action> Given(this IBddRunner runner, Action given) { return(new Scene <Action>(runner) .Given(given)); }
public ContextualBddRunner(IBddRunner coreRunner, Func <IDependencyResolver, object> contextResolver) { Core = coreRunner.Integrate().Core.WithContext(contextResolver); }
/// <summary> /// Runs test scenario by executing given steps in specified order.<br/> /// If given step throws, other are not executed.<br/> /// Scenario name is determined from the method name in which <see cref="RunScenarioAsync"/>() method is called.<br/> /// Scenario labels are determined from <see cref="LabelAttribute"/> attributes applied on scenario method.<br/> /// Step name is determined from corresponding action name.<br/> /// Example usage: /// <code> /// [Scenario] /// [Label("Ticket-1")] /// public Task Successful_login() /// { /// return Runner.RunScenarioAsync( /// Given_the_user_is_about_to_login, /// Given_the_user_entered_valid_login, /// Given_the_user_entered_valid_password, /// When_the_user_clicks_login_button, /// Then_the_login_operation_should_be_successful, /// Then_a_welcome_message_containing_user_name_should_be_returned); /// } /// </code> /// Expected step signature: /// <code> /// async Task Given_the_user_is_about_to_login() { /* ... */ } /// </code> /// </summary> /// <param name="runner">Runner.</param> /// <param name="steps">List of steps to execute in order.</param> public static async Task RunScenarioAsync(this IBddRunner runner, params Func <Task>[] steps) { await Basic(runner).RunScenarioAsync(steps); }
private static BasicScenarioRunner Basic(this IBddRunner runner) { return(new BasicScenarioRunner(runner.Integrate())); }
public void SetUp() { _builder = ScenarioMocks.CreateScenarioBuilder(); _runner = ScenarioMocks.CreateBddRunner(_builder); }
public ContextualBddRunner(IBddRunner coreRunner, Func <IDependencyResolver, object> contextResolver) { _configureScenarioContext = scenario => scenario.WithContext(contextResolver); _coreRunner = coreRunner.Integrate(); }
public ContextualBddRunner(IBddRunner coreRunner, Func <object> contextProvider, bool takeOwnership) { _configureScenarioContext = scenario => scenario.WithContext(contextProvider, takeOwnership); _coreRunner = coreRunner.Integrate(); }
/// <summary> /// Runs test scenario by executing given steps in specified order.<br/> /// If given step throws, other are not executed.<br/> /// Scenario name is determined from the method name in which <see cref="RunScenarioActionsAsync"/>() method is called.<br/> /// Scenario labels are determined from <see cref="LabelAttribute"/> attributes applied on scenario method.<br/> /// Step name is determined from corresponding action name.<br/> /// Example usage: /// <code> /// [Scenario] /// [Label("Ticket-1")] /// public Task Successful_login() /// { /// return Runner.RunScenarioActionsAsync( /// Given_the_user_is_about_to_login, /// Given_the_user_entered_valid_login, /// Given_the_user_entered_valid_password, /// When_the_user_clicks_login_button, /// Then_the_login_operation_should_be_successful, /// Then_a_welcome_message_containing_user_name_should_be_returned); /// } /// </code> /// Expected step signature: /// <code> /// async void Given_the_user_is_about_to_login() { /* ... */ } /// </code> /// or /// <code> /// void Given_the_user_is_about_to_login() { /* ... */ } /// </code> /// </summary> /// <param name="runner">Runner.</param> /// <param name="steps">List of steps to execute in order.</param> public static async Task RunScenarioActionsAsync(this IBddRunner runner, params Action[] steps) { await Basic(runner).RunScenarioAsync(steps); }
/// <summary> /// Returns runner that will be executing scenarios in dedicated context of <typeparamref name="TContext"/> type.<br/> /// The context instance will be created by calling default constructor just before scenario execution. /// /// All context instances implementing <see cref="IDisposable"/> interface will be disposed after scenario. /// </summary> /// <param name="runner"><see cref="IBddRunner"/> instance.</param> /// <typeparam name="TContext">Context type.</typeparam> /// <returns>Contextual runner.</returns> public static IBddRunner <TContext> WithContext <TContext>(this IBddRunner runner) where TContext : new() { return(new ContextualBddRunner <TContext>(runner, () => new TContext(), true)); }
/// <summary> /// Runs test scenario by executing given steps in specified order.<br/> /// If given step throws, other are not executed.<br/> /// Scenario name is determined from the method name in which <see cref="RunScenario"/>() method is called.<br/> /// Scenario labels are determined from <see cref="LabelAttribute"/> attributes applied on scenario method.<br/> /// Step name is determined from corresponding action name.<br/> /// Example usage: /// <code> /// [Scenario] /// [Label("Ticket-1")] /// public void Successful_login() /// { /// Runner.RunScenario( /// Given_the_user_is_about_to_login, /// Given_the_user_entered_valid_login, /// Given_the_user_entered_valid_password, /// When_the_user_clicks_login_button, /// Then_the_login_operation_should_be_successful, /// Then_a_welcome_message_containing_user_name_should_be_returned); /// } /// </code> /// Expected step signature: /// <code> /// void Given_the_user_is_about_to_login() { /* ... */ } /// </code> /// </summary> /// <param name="runner">Runner.</param> /// <param name="steps">List of steps to execute in order.</param> public static void RunScenario(this IBddRunner runner, params Action[] steps) { Basic(runner).RunScenario(steps); }
public void SetUp() { _runner = TestableFeatureRunnerRepository.GetRunner(GetType()).GetBddRunner(this); _executedSteps = new List <Tuple <string, object> >(); }
public ContextualBddRunner(IBddRunner coreRunner, Func <object> contextProvider, bool takeOwnership) { Core = coreRunner.Integrate().Core.WithContext(contextProvider, takeOwnership); }
public void SetUp() { _mockRunner = new Mock <ITestableBddRunner>(MockBehavior.Strict); _mockScenarioRunner = new Mock <IScenarioRunner>(); _runner = _mockRunner.Object; }
public void SetUp() { _feature = TestableFeatureRunnerRepository.GetRunner(GetType()); _runner = _feature.GetBddRunner(this); }
/// <summary> /// Specifies that scenario will be executed in dedicated context of <typeparamref name="TContext"/> type, created by <paramref name="contextFactory"/> function.<br/> /// The context instance will be created just before scenario execution.<br/> /// The <paramref name="takeOwnership"/> specifies if created context should be disposed (when implements <see cref="IDisposable"/> interface) by scenario runner. By default is it set to <c>true</c>. /// </summary> /// <typeparam name="TContext">Context type.</typeparam> /// <param name="runner"><see cref="IBddRunner"/> instance.</param> /// <param name="contextFactory">Context factory function.</param> /// <param name="takeOwnership">Specifies if scenario runner should take ownership of the context instance. If set to true and context instance implements <see cref="IDisposable"/>, it will be disposed after scenario finish.</param> /// <returns>Contextual runner.</returns> public static IBddRunner <TContext> WithContext <TContext>(this IBddRunner runner, Func <TContext> contextFactory, bool takeOwnership = true) { return(new ContextualBddRunner <TContext>(runner, () => contextFactory(), takeOwnership)); }