public void MsTestGeneratorShouldSetDescriptionCorrectlyWhenExampleSetIdentifierIsUsed()
        {
            SpecFlowGherkinParser parser = new SpecFlowGherkinParser(new CultureInfo("en-US"));

            using (var reader = new StringReader(SampleFeatureFileWithMultipleExampleSets))
            {
                SpecFlowFeature feature = parser.Parse(reader, null);
                Assert.IsNotNull(feature);

                var sampleTestGeneratorProvider = new MsTestGeneratorProvider(new CodeDomHelper(CodeDomProviderLanguage.CSharp));

                var           converter = CreateUnitTestConverter(sampleTestGeneratorProvider);
                CodeNamespace code      = converter.GenerateUnitTestFixture(feature, "TestClassName", "Target.Namespace");

                Assert.IsNotNull(code);
                var descriptionAttributeForFirstScenarioOutline = code.Class().Members().Single(m => m.Name == "SimpleScenarioOutline_ExampleSet0_Something").CustomAttributes().Single(a => a.Name == TestDescriptionAttributeName);
                descriptionAttributeForFirstScenarioOutline.ArgumentValues().First().Should().Be("Simple Scenario Outline: something");
                var descriptionAttributeForSecondScenarioOutline = code.Class().Members().Single(m => m.Name == "SimpleScenarioOutline_ExampleSet0_SomethingElse").CustomAttributes().Single(a => a.Name == TestDescriptionAttributeName);
                descriptionAttributeForSecondScenarioOutline.ArgumentValues().First().Should().Be("Simple Scenario Outline: something else");
                var descriptionAttributeForThirdScenarioOutline = code.Class().Members().Single(m => m.Name == "SimpleScenarioOutline_ExampleSet1_Another").CustomAttributes().Single(a => a.Name == TestDescriptionAttributeName);
                descriptionAttributeForThirdScenarioOutline.ArgumentValues().First().Should().Be("Simple Scenario Outline: another");
                var descriptionAttributeForFourthScenarioOutline = code.Class().Members().Single(m => m.Name == "SimpleScenarioOutline_ExampleSet1_AndAnother").CustomAttributes().Single(a => a.Name == TestDescriptionAttributeName);
                descriptionAttributeForFourthScenarioOutline.ArgumentValues().First().Should().Be("Simple Scenario Outline: and another");
            }
        }
Пример #2
0
        public List <SemanticParserException> Validate(SpecFlowFeature feature)
        {
            var errors = new List <SemanticParserException>();

            foreach (var scenarioDefinition in feature.ScenarioDefinitions)
            {
                var scenarioOutline = scenarioDefinition as ScenarioOutline;
                if (scenarioOutline != null)
                {
                    foreach (var example in scenarioOutline.Examples)
                    {
                        if (example.TableHeader != null)
                        {
                            var duplicateExamples = example.TableHeader.Cells
                                                    .GroupBy(g => g.Value)
                                                    .Where(g => g.Count() > 1);

                            foreach (var duplicateExample in duplicateExamples)
                            {
                                var message = $"Scenario Outline '{scenarioOutline.Name}' already contains an example column with header '{duplicateExample.Key}'";
                                errors.Add(new SemanticParserException(message, scenarioOutline.Location));
                            }
                        }
                    }
                }
            }

            return(errors);
        }
Пример #3
0
        private void AddBackgroundLineTest(SpecFlowFeature feature, SpecFlowStep step)
        {
            // Test method
            var testMethod = new CodeMemberMethod
            {
                Attributes = MemberAttributes.Public,
                Name       = NamingHelper.GetTestName(feature, step)
            };


            testMethod.Statements.Add(new CodeMethodInvokeExpression(
                                          new CodeMethodReferenceExpression(
                                              new CodeThisReferenceExpression(),
                                              NamingHelper.TestWrapperMethodName),
                                          new CodeDelegateCreateExpression(new CodeTypeReference(typeof(Action)),
                                                                           new CodeThisReferenceExpression(), NamingHelper.GetTestStepsName(feature, step)),
                                          new CodePrimitiveExpression(step.Location.Line)));

            _context.UnitTestGeneratorProvider.SetTestMethod(_context, testMethod, NamingHelper.GetTestName(feature, step));

            _context.TestClass.Members.Add(testMethod);

            // Test steps
            var stepsMethod = new CodeMemberMethod
            {
                Attributes = MemberAttributes.Private,
                Name       = NamingHelper.GetTestStepsName(feature, step)
            };

            AddActionStatementsForBackgroundStep(feature, stepsMethod.Statements, step);

            _context.TestClass.Members.Add(stepsMethod);
        }
Пример #4
0
        public List <SemanticParserException> Validate(SpecFlowFeature feature)
        {
            var errors = new List <SemanticParserException>();

            foreach (var scenarioDefinition in feature.ScenarioDefinitions)
            {
                var scenarioOutline = scenarioDefinition as ScenarioOutline;
                if (scenarioOutline != null)
                {
                    var duplicateExamples = scenarioOutline.Examples
                                            .Where(e => !String.IsNullOrWhiteSpace(e.Name))
                                            .Where(e => e.Tags.All(t => t.Name != "ignore"))
                                            .GroupBy(e => e.Name, e => e).Where(g => g.Count() > 1);

                    foreach (var duplicateExample in duplicateExamples)
                    {
                        var message = string.Format("Scenario Outline '{0}' already contains an example with name '{1}'", scenarioOutline.Name, duplicateExample.Key);
                        var semanticParserException = new SemanticParserException(message, duplicateExample.ElementAt(1).Location);
                        errors.Add(semanticParserException);
                    }
                }
            }

            return(errors);
        }
Пример #5
0
 private void SerializeFeature(SpecFlowFeature feature, string fileName)
 {
     using (var writer = new StreamWriter(fileName, false, Encoding.UTF8))
     {
         SerializeFeature(feature, writer);
     }
 }
        public List <string> GetFeatureVariantTagValues(SpecFlowFeature feature)
        {
            var tags = FeatureTags(feature)?.Select(a => a.Name.Split(':')[1]).ToList();

            FeatureHasVariantTags = tags.Count > 0;
            return(tags);
        }
Пример #7
0
        private void GenerateTestBody(
            TestClassGenerationContext generationContext,
            StepsContainer scenario,
            CodeMemberMethod testMethod,
            SpecFlowFeature feature,
            CodeExpression additionalTagsExpression = null,
            ParameterSubstitution paramToIdentifier = null)
        {
            //call test setup
            //ScenarioInfo scenarioInfo = new ScenarioInfo("xxxx", tags...);
            CodeExpression tagsExpression;

            if (additionalTagsExpression == null)
            {
                tagsExpression = GetStringArrayExpression(scenario.GetTags());
            }
            else if (!scenario.HasTags())
            {
                tagsExpression = additionalTagsExpression;
            }
            else
            {
                // merge tags list
                // var tags = tags1
                // if (tags2 != null)
                //   tags = Enumerable.ToArray(Enumerable.Concat(tags1, tags1));
                testMethod.Statements.Add(
                    new CodeVariableDeclarationStatement(typeof(string[]), "__tags", GetStringArrayExpression(scenario.GetTags())));
                tagsExpression = new CodeVariableReferenceExpression("__tags");
                testMethod.Statements.Add(
                    new CodeConditionStatement(
                        new CodeBinaryOperatorExpression(
                            additionalTagsExpression,
                            CodeBinaryOperatorType.IdentityInequality,
                            new CodePrimitiveExpression(null)),
                        new CodeAssignStatement(
                            tagsExpression,
                            new CodeMethodInvokeExpression(
                                new CodeTypeReferenceExpression(typeof(Enumerable)),
                                "ToArray",
                                new CodeMethodInvokeExpression(
                                    new CodeTypeReferenceExpression(typeof(Enumerable)),
                                    "Concat",
                                    tagsExpression,
                                    additionalTagsExpression)))));
            }

            testMethod.Statements.Add(
                new CodeVariableDeclarationStatement(typeof(ScenarioInfo), "scenarioInfo",
                                                     new CodeObjectCreateExpression(typeof(ScenarioInfo),
                                                                                    new CodePrimitiveExpression(scenario.Name),
                                                                                    new CodePrimitiveExpression(scenario.Description),
                                                                                    tagsExpression)));

            GenerateScenarioInitializeCall(generationContext, scenario, testMethod);

            GenerateTestMethodBody(generationContext, scenario, testMethod, paramToIdentifier, feature);

            GenerateScenarioCleanupMethodCall(generationContext, testMethod);
        }
 public void CreateUnitTests(SpecFlowFeature feature, TestClassGenerationContext generationContext)
 {
     foreach (var scenarioDefinition in feature.ScenarioDefinitions)
     {
         CreateUnitTest(feature, generationContext, scenarioDefinition);
     }
 }
        private SpecFlowDocument CreateFlavoredFeature(SpecFlowDocument specFlowDocument, IEnumerable <Flavor> flavors)
        {
            var sourceFeature = specFlowDocument.SpecFlowFeature;

            // Strip off all the flavor tags we no longer want.
            var tags = sourceFeature.Tags
                       .Where(tag => !IsFlavorTag(tag))
                       .ToList();

            // Add the flavors specified.
            foreach (var flavor in flavors)
            {
                tags.Add(new Tag(null, $"{flavor.Category}: {flavor.Value}"));
            }

            // Generate a copy of the feature with the tags specified.
            // TODO: Try filtering out all scenarios which don't match.
            var flavoredFeature = new SpecFlowFeature(
                tags.ToArray(),
                sourceFeature.Location,
                sourceFeature.Language,
                sourceFeature.Keyword,
                sourceFeature.Name,
                sourceFeature.Description,
                sourceFeature.Children.ToArray());

            return(new SpecFlowDocument(
                       flavoredFeature,
                       specFlowDocument.Comments.ToArray(),
                       specFlowDocument.SourceFilePath));
        }
Пример #10
0
 private string SerializeFeature(SpecFlowFeature feature)
 {
     using (var writer = new Utf8StringWriter())
     {
         SerializeFeature(feature, writer);
         return(writer.ToString());
     }
 }
Пример #11
0
        private void SerializeFeature(SpecFlowFeature feature, TextWriter writer)
        {
            var oldFeature = CompatibleAstConverter.ConvertToCompatibleFeature(feature);

            oldFeature.SourceFile = null;
            XmlSerializer serializer = new XmlSerializer(typeof(Feature));

            serializer.Serialize(writer, oldFeature);
        }
Пример #12
0
        public static SpecFlowDocument CreateDocument(string[] tags = null, string[] scenarioTags = null)
        {
            tags = tags ?? new string[0];

            var scenario1 = new Scenario(GetTags(scenarioTags), null, "Scenario", "scenario1 title", "", new Step[0]);

            var specFlowFeature = new SpecFlowFeature(GetTags(tags), null, "en", "feature", "title", "desc", new ScenarioDefinition[] { scenario1 });

            return(new SpecFlowDocument(specFlowFeature, new Comment[0], null));
        }
Пример #13
0
        public static string GetTestName(SpecFlowFeature feature, SpecFlowStep step)
        {
            int digitCountInTotalLines =
                feature.ScenarioDefinitions.Last().Steps.Last().Location.Line.ToString().Length;

            string lineNumberLeadingZeros =
                new string('0', digitCountInTotalLines - step.Location.Line.ToString().Length);

            return($"TestLine{lineNumberLeadingZeros}{step.Location.Line}{step.Text.ToIdentifier()}");
        }
        public void Should_support_case_insensitive_ignore_tag_on_feature()
        {
            var generator = CreateUnitTestFeatureGenerator();

            SpecFlowFeature theFeature = ParserHelper.CreateFeature(new string[] { "IgnoRe" });

            generator.GenerateUnitTestFixture(theFeature, "dummy", "dummyNS");

            unitTestGeneratorProviderMock.Verify(ug => ug.SetTestClassIgnore(It.IsAny <TestClassGenerationContext>()));
        }
        public void Should_not_call_SetTestMethodIgnore_when_feature_ignored()
        {
            var generator = CreateUnitTestFeatureGenerator();

            SpecFlowFeature theFeature = ParserHelper.CreateFeature(new string[] { "ignore" });

            generator.GenerateUnitTestFixture(theFeature, "dummy", "dummyNS");

            unitTestGeneratorProviderMock.Verify(ug => ug.SetTestMethodIgnore(It.IsAny <TestClassGenerationContext>(), It.IsAny <CodeMemberMethod>()), Times.Never());
        }
        public void Should_support_case_insensitive_ignore_tag_on_scenario()
        {
            var generator = CreateUnitTestFeatureGenerator();

            SpecFlowFeature theFeature = ParserHelper.CreateFeature(scenarioTags: new[] { "IgnoRe" });

            generator.GenerateUnitTestFixture(theFeature, "dummy", "dummyNS");

            unitTestGeneratorProviderMock.Verify(ug => ug.SetTestMethodIgnore(It.IsAny <TestClassGenerationContext>(), It.IsAny <CodeMemberMethod>()));
        }
        public void Should_not_pass_ignore_as_test_class_category()
        {
            var generator = CreateUnitTestFeatureGenerator();

            SpecFlowFeature theFeature = ParserHelper.CreateFeature(new string[] { "ignore", "other" });

            generator.GenerateUnitTestFixture(theFeature, "dummy", "dummyNS");

            unitTestGeneratorProviderMock.Verify(ug => ug.SetTestClassCategories(It.IsAny <TestClassGenerationContext>(), It.Is <IEnumerable <string> >(cats => !cats.Contains("ignore"))));
        }
        public void Should_TagFilteredFeatureGeneratorProvider_not_be_applied_for_feature_with_no_tgas()
        {
            container.RegisterTypeAs <TestTagFilteredFeatureGeneratorProvider, IFeatureGeneratorProvider>("mytag");

            SpecFlowFeature theFeature = ParserHelper.CreateAnyFeature();

            var featureGeneratorRegistry = CreateFeatureGeneratorRegistry();

            var generator = featureGeneratorRegistry.CreateGenerator(theFeature);

            generator.Should().NotBe(TestTagFilteredFeatureGeneratorProvider.DummyGenerator);
        }
        public void Should_TagFilteredFeatureGeneratorProvider_applied_for_registered_tag_name_with_at()
        {
            container.RegisterTypeAs <TestTagFilteredFeatureGeneratorProvider, IFeatureGeneratorProvider>("@mytag");

            SpecFlowFeature theFeature = ParserHelper.CreateAnyFeature(tags: new[] { "mytag" });

            var featureGeneratorRegistry = CreateFeatureGeneratorRegistry();

            var generator = featureGeneratorRegistry.CreateGenerator(theFeature);

            generator.Should().Be(TestTagFilteredFeatureGeneratorProvider.DummyGenerator);
        }
Пример #20
0
 public static SpecFlowDocument Clone(this SpecFlowDocument d,
                                      SpecFlowFeature feature        = null,
                                      IEnumerable <Comment> comments = null,
                                      string sourceFilePath          = null
                                      )
 {
     return(new SpecFlowDocument(
                feature ?? d.SpecFlowFeature,
                (comments ?? d.Comments)?.ToArray(),
                new SpecFlowDocumentLocation(sourceFilePath ?? d.SourceFilePath)
                ));
 }
        public List <SemanticParserException> Validate(SpecFlowFeature feature)
        {
            var errors = new List <SemanticParserException>();
            var duplicatedScenarios = feature.ScenarioDefinitions.GroupBy(sd => sd.Name, sd => sd).Where(g => g.Count() > 1).ToArray();

            errors.AddRange(
                duplicatedScenarios.Select(g =>
                                           new SemanticParserException(
                                               string.Format("Feature file already contains a scenario with name '{0}'", g.Key),
                                               g.ElementAt(1).Location)));

            return(errors);
        }
Пример #22
0
        public static SpecFlowDocument CreateDocumentWithScenarioOutline(string[] tags = null, string[] scenarioOutlineTags = null, string[] examplesTags = null)
        {
            tags = tags ?? new string[0];

            var scenario1 = new ScenarioOutline(GetTags(scenarioOutlineTags), null, "Scenario Outline", "scenario outline1 title", "", new Step[0], new []
            {
                new Examples(GetTags(examplesTags), null, "Examples", "examples name", "", new Gherkin.Ast.TableRow(null, new [] { new TableCell(null, "col1"), }), new Gherkin.Ast.TableRow[0])
            });

            var specFlowFeature = new SpecFlowFeature(GetTags(tags), null, "en", "feature", "title", "desc", new ScenarioDefinition[] { scenario1 });

            return(new SpecFlowDocument(specFlowFeature, new Comment[0], null));
        }
        private SpecFlowDocument CreateSpecFlowDocument(SpecFlowDocument originalSpecFlowDocument, SpecFlowFeature originalFeature, List <IHasLocation> scenarioDefinitions)
        {
            var newFeature = new SpecFlowFeature(originalFeature.Tags.ToArray(),
                                                 originalFeature.Location,
                                                 originalFeature.Language,
                                                 originalFeature.Keyword,
                                                 originalFeature.Name,
                                                 originalFeature.Description,
                                                 scenarioDefinitions.ToArray());

            var newDocument = new SpecFlowDocument(newFeature, originalSpecFlowDocument.Comments.ToArray(), originalSpecFlowDocument.DocumentLocation);

            return(newDocument);
        }
Пример #24
0
 public static Feature ConvertToCompatibleFeature(SpecFlowFeature gherkin3Feature)
 {
     return new Feature(gherkin3Feature.Keyword, gherkin3Feature.Name,
         ConvertToCompatibleTags(gherkin3Feature.Tags),
         gherkin3Feature.Description,
         ConvertToCompatibleBackground(gherkin3Feature.Background),
         ConvertToCompatibleScenarios(gherkin3Feature.ScenarioDefinitions),
         ConvertToCompatibleComments(gherkin3Feature.Comments))
     {
         FilePosition = ConvertToCompatibleFilePosition(gherkin3Feature.Location),
         Language = gherkin3Feature.Language,
         SourceFile = gherkin3Feature.SourceFilePath
     };
 }
Пример #25
0
 public static Feature ConvertToCompatibleFeature(SpecFlowFeature gherkin3Feature)
 {
     return(new Feature(gherkin3Feature.Keyword, gherkin3Feature.Name,
                        ConvertToCompatibleTags(gherkin3Feature.Tags),
                        gherkin3Feature.Description,
                        ConvertToCompatibleBackground(gherkin3Feature.Background),
                        ConvertToCompatibleScenarios(gherkin3Feature.ScenarioDefinitions),
                        ConvertToCompatibleComments(gherkin3Feature.Comments))
     {
         FilePosition = ConvertToCompatibleFilePosition(gherkin3Feature.Location),
         Language = gherkin3Feature.Language,
         SourceFile = gherkin3Feature.SourceFilePath
     });
 }
Пример #26
0
 private void FixStepKeyWordForScenarioStep(SpecFlowFeature feature, SpecFlowStep executionStep, SpecFlowStep testingStep, out StepKeyword stepKeyWord, out string keyWord)
 {
     stepKeyWord = executionStep.StepKeyword;
     keyWord     = executionStep.Keyword;
     if (executionStep.StepKeyword == StepKeyword.And)
     {
         int scenarioStepIndex = feature.Background.Steps.ToList().IndexOf(executionStep);
         int stepIndex         = feature.Background.Steps.ToList().IndexOf(testingStep);
         if (scenarioStepIndex == stepIndex + 1)
         {
             stepKeyWord = testingStep.StepKeyword;
             keyWord     = testingStep.Keyword;
         }
     }
 }
        private void CreateUnitTest(SpecFlowFeature feature, TestClassGenerationContext generationContext, StepsContainer scenarioDefinition)
        {
            if (string.IsNullOrEmpty(scenarioDefinition.Name))
            {
                throw new TestGeneratorException("The scenario must have a title specified.");
            }

            if (scenarioDefinition is ScenarioOutline scenarioOutline)
            {
                GenerateScenarioOutlineTest(generationContext, scenarioOutline, feature);
            }
            else
            {
                GenerateTest(generationContext, (Scenario)scenarioDefinition, feature);
            }
        }
        public TestClassGenerationContext(IUnitTestGeneratorProvider unitTestGeneratorProvider, SpecFlowFeature feature, CodeNamespace ns, CodeTypeDeclaration testClass, CodeMemberField testRunnerField, CodeMemberMethod testClassInitializeMethod, CodeMemberMethod testClassCleanupMethod, CodeMemberMethod testInitializeMethod, CodeMemberMethod testCleanupMethod, CodeMemberMethod scenarioInitializeMethod, CodeMemberMethod scenarioCleanupMethod, CodeMemberMethod featureBackgroundMethod, bool generateRowTests)
        {
            UnitTestGeneratorProvider = unitTestGeneratorProvider;
            Feature                   = feature;
            Namespace                 = ns;
            TestClass                 = testClass;
            TestRunnerField           = testRunnerField;
            TestClassInitializeMethod = testClassInitializeMethod;
            TestClassCleanupMethod    = testClassCleanupMethod;
            TestInitializeMethod      = testInitializeMethod;
            TestCleanupMethod         = testCleanupMethod;
            ScenarioInitializeMethod  = scenarioInitializeMethod;
            ScenarioCleanupMethod     = scenarioCleanupMethod;
            FeatureBackgroundMethod   = featureBackgroundMethod;
            GenerateRowTests          = generateRowTests;

            CustomData = new Dictionary <string, object>();
        }
        public void Should_call_provider_wiht_the_given_feature()
        {
            var dummyGenerator = new Mock <IFeatureGenerator>().Object;

            var genericHighPrioProvider = new Mock <IFeatureGeneratorProvider>();

            genericHighPrioProvider.Setup(p => p.CreateGenerator(It.IsAny <SpecFlowFeature>())).Returns(dummyGenerator);
            genericHighPrioProvider.Setup(p => p.CanGenerate(It.IsAny <SpecFlowFeature>())).Returns(true); // generic
            genericHighPrioProvider.Setup(p => p.Priority).Returns(1);                                     // high-prio

            container.RegisterInstanceAs(genericHighPrioProvider.Object, "custom");

            var featureGeneratorRegistry = CreateFeatureGeneratorRegistry();

            SpecFlowFeature theFeature = ParserHelper.CreateAnyFeature();

            featureGeneratorRegistry.CreateGenerator(theFeature);

            genericHighPrioProvider.Verify(p => p.CreateGenerator(theFeature), Times.Once());
        }
        public void Should_skip_high_priority_provider_when_not_applicable()
        {
            var dummyGenerator = new Mock <IFeatureGenerator>().Object;

            SpecFlowFeature theFeature = ParserHelper.CreateAnyFeature();

            var genericHighPrioProvider = new Mock <IFeatureGeneratorProvider>();

            genericHighPrioProvider.Setup(p => p.CreateGenerator(It.IsAny <SpecFlowFeature>())).Returns(dummyGenerator);
            genericHighPrioProvider.Setup(p => p.CanGenerate(theFeature)).Returns(false); // not applicable for aFeature
            genericHighPrioProvider.Setup(p => p.Priority).Returns(1);                    // high-prio

            container.RegisterInstanceAs(genericHighPrioProvider.Object, "custom");

            var featureGeneratorRegistry = CreateFeatureGeneratorRegistry();

            var generator = featureGeneratorRegistry.CreateGenerator(theFeature);

            generator.Should().BeOfType <UnitTestFeatureGenerator>();
        }
        public List <SemanticParserException> Validate(SpecFlowFeature feature)
        {
            var errors = new List <SemanticParserException>();

            foreach (var scenarioDefinition in feature.ScenarioDefinitions)
            {
                var scenarioOutline = scenarioDefinition as ScenarioOutline;
                if (scenarioOutline != null)
                {
                    if (DoesntHavePopulatedExamples(scenarioOutline))
                    {
                        var message = string.Format("Scenario Outline '{0}' has no examples defined", scenarioOutline.Name);
                        var semanticParserException = new SemanticParserException(message, scenarioDefinition.Location);
                        errors.Add(semanticParserException);
                    }
                }
            }

            return(errors);
        }