public void RunGherkinBasedTests(IMessageSerializer messageSerializer) { WriteOutput($"Starting Gherkin-based tests with serializer: {messageSerializer.GetType().Name}"); Gremlin.InstantiateTranslationsForTestRun(); var stepDefinitionTypes = GetStepDefinitionTypes(); var results = new List <ResultFeature>(); using var scenarioData = new ScenarioData(messageSerializer); CommonSteps.ScenarioData = scenarioData; foreach (var feature in GetFeatures()) { var resultFeature = new ResultFeature(feature); results.Add(resultFeature); foreach (var child in feature.Children) { var scenario = (Scenario)child; var failedSteps = new Dictionary <Step, Exception>(); resultFeature.Scenarios[scenario] = failedSteps; if (IgnoredScenarios.TryGetValue(scenario.Name, out var reason)) { failedSteps.Add(scenario.Steps.First(), new IgnoreException(reason)); continue; } StepBlock? currentStep = null; StepDefinition stepDefinition = null; foreach (var step in scenario.Steps) { var previousStep = currentStep; currentStep = GetStepBlock(currentStep, step.Keyword); if (currentStep == StepBlock.Given && previousStep != StepBlock.Given) { stepDefinition = GetStepDefinitionInstance(stepDefinitionTypes, step.Text); } if (stepDefinition == null) { throw new NotSupportedException( $"Step '{step.Text} not supported without a 'Given' step first"); } scenarioData.CurrentScenario = scenario; var result = ExecuteStep(stepDefinition, currentStep.Value, step); if (result != null) { failedSteps.Add(step, result); // Stop processing scenario break; } } } } OutputResults(results); WriteOutput($"Finished Gherkin-based tests with serializer: {messageSerializer.GetType().Name}."); }
public void RunGherkinBasedTests() { WriteOutput("Starting Gherkin-based tests"); var stepDefinitionTypes = GetStepDefinitionTypes(); var results = new List <ResultFeature>(); foreach (var feature in GetFeatures()) { var resultFeature = new ResultFeature(feature); results.Add(resultFeature); foreach (var scenario in feature.Children) { var failedSteps = new Dictionary <Step, Exception>(); resultFeature.Scenarios[scenario] = failedSteps; if (IgnoredScenarios.TryGetValue(scenario.Name, out var reason)) { failedSteps.Add(scenario.Steps.First(), new IgnoreException(reason)); continue; } StepBlock? currentStep = null; StepDefinition stepDefinition = null; foreach (var step in scenario.Steps) { var previousStep = currentStep; currentStep = GetStepBlock(currentStep, step.Keyword); if (currentStep == StepBlock.Given && previousStep != StepBlock.Given) { stepDefinition?.Dispose(); stepDefinition = GetStepDefinitionInstance(stepDefinitionTypes, step.Text); } if (stepDefinition == null) { throw new NotSupportedException( $"Step '{step.Text} not supported without a 'Given' step first"); } ScenarioData.CurrentScenario = scenario; var result = ExecuteStep(stepDefinition, currentStep.Value, step); if (result != null) { failedSteps.Add(step, result); // Stop processing scenario break; } } } } OutputResults(results); WriteOutput("Finished Gherkin-based tests"); ScenarioData.Shutdown(); }
private Exception ExecuteStep(StepDefinition instance, StepBlock stepBlock, Step step) { var attribute = Attributes[stepBlock]; var methodAndParameters = instance.GetType().GetMethods() .Select(m => { var attr = (BddAttribute)m.GetCustomAttribute(attribute); if (attr == null) { return(null); } var match = Regex.Match(step.Text, attr.Message); if (!match.Success) { return(null); } var parameters = new List <object>(); for (var i = 1; i < match.Groups.Count; i++) { parameters.Add(match.Groups[i].Value); } if (step.Argument is DocString) { parameters.Add(((DocString)step.Argument).Content); } else if (step.Argument != null) { parameters.Add(step.Argument); } var methodParameters = m.GetParameters(); for (var i = parameters.Count; i < methodParameters.Length; i++) { // Try to complete with default parameter values var paramInfo = methodParameters[i]; if (!paramInfo.HasDefaultValue) { break; } parameters.Add(paramInfo.DefaultValue); } if (methodParameters.Length != parameters.Count) { return(null); } return(Tuple.Create(m, parameters.ToArray())); }) .FirstOrDefault(t => t != null); if (methodAndParameters == null) { throw new InvalidOperationException( $"There is no step definition method for {stepBlock} '{step.Text}'"); } try { var method = methodAndParameters.Item1; var parameters = methodAndParameters.Item2; var parameterInfos = method.GetParameters(); for (var i = 0; i < parameterInfos.Length; i++) { var paramInfo = parameterInfos[i]; // Do some minimal conversion => regex capturing groups to int if (paramInfo.ParameterType == typeof(int)) { parameters[i] = Convert.ToInt32(parameters[i]); } } method.Invoke(instance, parameters); } catch (TargetInvocationException ex) { // Exceptions should not be thrown // Should be captured for result return(ex.InnerException); } catch (Exception ex) { return(ex); } // Success return(null); }