Пример #1
0
        private async Task <RunSummary> InvokeScenarioMethodAsync(object scenarioClassInstance)
        {
            var backgroundStepDefinitions = new List <IStepDefinition>();
            var scenarioStepDefinitions   = new List <IStepDefinition>();

            await this.aggregator.RunAsync(async() =>
            {
                using (CurrentThread.EnterStepDefinitionContext())
                {
                    foreach (var backgroundMethod in this.scenario.TestCase.TestMethod.TestClass.Class
                             .GetMethods(false)
                             .Where(candidate => candidate.GetCustomAttributes(typeof(BackgroundAttribute)).Any())
                             .Select(method => method.ToRuntimeMethod()))
                    {
                        await this.timer.AggregateAsync(() =>
                                                        backgroundMethod.InvokeAsync(scenarioClassInstance, null));
                    }

                    backgroundStepDefinitions.AddRange(CurrentThread.StepDefinitions);
                }

                using (CurrentThread.EnterStepDefinitionContext())
                {
                    await this.timer.AggregateAsync(() =>
                                                    this.scenarioMethod.InvokeAsync(scenarioClassInstance, this.scenarioMethodArguments));

                    scenarioStepDefinitions.AddRange(CurrentThread.StepDefinitions);
                }
            });

            var runSummary = new RunSummary {
                Time = this.timer.Total
            };

            if (!this.aggregator.HasExceptions)
            {
                runSummary.Aggregate(await this.InvokeStepsAsync(backgroundStepDefinitions, scenarioStepDefinitions));
            }

            return(runSummary);
        }
        private async Task <RunSummary> InvokeScenarioMethodAsync(object scenarioClassInstance)
        {
            var backgroundSteps = new List <IStepDefinition>();
            var scenarioSteps   = new List <IStepDefinition>();
            var tearDownSteps   = new List <IStepDefinition>();

            await this._aggregator.RunAsync(async() =>
            {
                // We leverage this for both Background and TearDown methods.
                async Task OnDiscoverSupportMethodsAsync <TAttribute>(
                    IScenario scenario, ExecutionTimer timer)
                where TAttribute : SupportMethodAttribute
                {
                    var methods = scenario.TestCase.TestMethod.TestClass.Class
                                  .GetMethods(false)
                                  .Where(candidate => candidate.GetCustomAttributes(typeof(TAttribute)).Any())
                                  .Select(method => method.ToRuntimeMethod())
                                  // #2 MWP 2020-07-01 12:28:03 PM: the rubber meeting the road here.
                                  .OrderBy(method => method, new MethodInfoComparer()).ToList();

                    // Thus ensuring correct front to back Background, reverse TearDown.
                    if (typeof(TAttribute) == typeof(TearDownAttribute))
                    {
                        methods.Reverse();
                    }

                    foreach (var method in methods)
                    {
                        /* #4 MWP 2020-07-09 05:47:25 PM / We support seeding default values into
                         * Background methods with parameters. However, this is the extent of what
                         * we can accomplish there. It does not make any sense to cross any Theory
                         * dataRow bridges for Background methods. */
                        var argTypes = method.GetParameters().Select(param => param.ParameterType).ToArray();
                        var args     = argTypes.Select(paramType => paramType.GetDefault()).ToArray();

                        var convertedArgs = Reflector.ConvertArguments(args, argTypes);
                        convertedArgs     = convertedArgs.Any() ? convertedArgs : null;

                        await timer.AggregateAsync(() => method.InvokeAsync(scenarioClassInstance, convertedArgs));
                    }
                }

                using (CurrentThread.EnterStepDefinitionContext())
                {
                    await OnDiscoverSupportMethodsAsync <BackgroundAttribute>(this._scenario, this._timer);

                    backgroundSteps.AddRange(CurrentThread.StepDefinitions);
                }

                using (CurrentThread.EnterStepDefinitionContext())
                {
                    await this._timer.AggregateAsync(() => this._scenarioMethod.InvokeAsync(scenarioClassInstance, this._scenarioMethodArguments));

                    scenarioSteps.AddRange(CurrentThread.StepDefinitions);
                }

                // MWP Sun, 06 Dec 2020 11:00:56 AM / Rinse and repeat Background, except for TearDown...
                using (CurrentThread.EnterStepDefinitionContext())
                {
                    await OnDiscoverSupportMethodsAsync <TearDownAttribute>(this._scenario, this._timer);

                    tearDownSteps.AddRange(CurrentThread.StepDefinitions);
                }
            });

            var runSummary = new RunSummary {
                Time = this._timer.Total
            };

            if (!this._aggregator.HasExceptions)
            {
                // Assumes Scenario for StepDefinitionType.
                backgroundSteps.ForEach(x => x.StepDefinitionType = StepType.Background);
                tearDownSteps.ForEach(x => x.StepDefinitionType   = StepType.TearDown);
                runSummary.Aggregate(await this.InvokeStepsAsync(backgroundSteps, scenarioSteps, tearDownSteps));
            }

            return(runSummary);
        }