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)); }
public void CreateTestClassStructure(string testClassName, SpecFlowDocument document) { var generatedTypeDeclaration = _codeDomHelper.CreateGeneratedTypeDeclaration(testClassName); CodeNamespace.Types.Add(generatedTypeDeclaration); GenerationContext = new TestClassGenerationContext(_testGeneratorProvider, document, CodeNamespace, generatedTypeDeclaration, generatedTypeDeclaration.DeclareTestRunnerMember <ITestRunner>("testRunner"), generatedTypeDeclaration.CreateMethod(), generatedTypeDeclaration.CreateMethod(), generatedTypeDeclaration.CreateMethod(), generatedTypeDeclaration.CreateMethod(), generatedTypeDeclaration.CreateMethod(), generatedTypeDeclaration.CreateMethod(), generatedTypeDeclaration.CreateMethod(), document.SpecFlowFeature.HasFeatureBackground() ? generatedTypeDeclaration.CreateMethod() : null, _testGeneratorProvider.GetTraits().HasFlag(UnitTestGeneratorTraits.RowTests) && _specFlowConfiguration.AllowRowTests); }
public void Should_initialize_testOutputHelper_field_in_constructor() { SpecFlowGherkinParser parser = new SpecFlowGherkinParser(new CultureInfo("en-US")); using (var reader = new StringReader(SampleFeatureFile)) { SpecFlowDocument document = parser.Parse(reader, null); Assert.IsNotNull(document); var provider = new XUnit2TestGeneratorProvider(new CodeDomHelper(CodeDomProviderLanguage.CSharp)); var converter = provider.CreateUnitTestConverter(); CodeNamespace code = converter.GenerateUnitTestFixture(document, "TestClassName", "Target.Namespace"); Assert.IsNotNull(code); var classContructor = code.Class().Members().Single(m => m.Name == ".ctor"); classContructor.Should().NotBeNull(); classContructor.Parameters.Count.Should().Be(2); classContructor.Parameters[1].Type.BaseType.Should().Be("Xunit.Abstractions.ITestOutputHelper"); classContructor.Parameters[1].Name.Should().Be("testOutputHelper"); var initOutputHelper = classContructor.Statements.OfType <CodeAssignStatement>().First(); initOutputHelper.Should().NotBeNull(); ((CodeFieldReferenceExpression)(initOutputHelper.Left)).FieldName.Should().Be("_testOutputHelper"); ((CodeVariableReferenceExpression)(initOutputHelper.Right)).VariableName.Should().Be("testOutputHelper"); } }
public CodeNamespace GenerateUnitTestFixture(SpecFlowDocument document, string testClassName, string targetNamespace) { var codeNamespace = CreateNamespace(targetNamespace); var feature = document.SpecFlowFeature; testClassName = testClassName ?? string.Format(TestClassNameFormat, feature.Name.ToIdentifier()); var generationContext = CreateTestClassStructure(codeNamespace, testClassName, document); SetupTestClass(generationContext); SetupTestClassInitializeMethod(generationContext); SetupTestClassCleanupMethod(generationContext); SetupScenarioStartMethod(generationContext); SetupScenarioInitializeMethod(generationContext); _scenarioPartHelper.SetupFeatureBackground(generationContext); SetupScenarioCleanupMethod(generationContext); SetupTestInitializeMethod(generationContext); SetupTestCleanupMethod(generationContext); _unitTestMethodGenerator.CreateUnitTests(feature, generationContext); //before returning the generated code, call the provider's method in case the generated code needs to be customized _testGeneratorProvider.FinalizeTestClass(generationContext); return(codeNamespace); }
public void Should_register_testOutputHelper_on_scenario_setup() { SpecFlowGherkinParser parser = new SpecFlowGherkinParser(new CultureInfo("en-US")); using (var reader = new StringReader(SampleFeatureFile)) { SpecFlowDocument document = parser.Parse(reader, null); Assert.IsNotNull(document); var provider = new XUnit2TestGeneratorProvider(new CodeDomHelper(CodeDomProviderLanguage.CSharp)); var converter = provider.CreateUnitTestConverter(); CodeNamespace code = converter.GenerateUnitTestFixture(document, "TestClassName", "Target.Namespace"); Assert.IsNotNull(code); var scenarioStartMethod = code.Class().Members().Single(m => m.Name == @"ScenarioSetup"); scenarioStartMethod.Statements.Count.Should().Be(2); var expression = (scenarioStartMethod.Statements[1] as CodeExpressionStatement).Expression; var method = (expression as CodeMethodInvokeExpression).Method; (method.TargetObject as CodePropertyReferenceExpression).PropertyName.Should().Be("ScenarioContainer"); method.MethodName.Should().Be("RegisterInstanceAs"); method.TypeArguments.Should().NotBeNullOrEmpty(); method.TypeArguments[0].BaseType.Should().Be("Xunit.Abstractions.ITestOutputHelper"); ((expression as CodeMethodInvokeExpression).Parameters[0] as CodeVariableReferenceExpression).VariableName.Should().Be("_testOutputHelper"); } }
public void MsTestGeneratorShouldInvokeFeatureSetupMethodWithGlobalNamespaceAlias() { SpecFlowGherkinParser parser = new SpecFlowGherkinParser(new CultureInfo("en-US")); using (var reader = new StringReader(SampleFeatureFileWithMultipleExampleSets)) { SpecFlowDocument document = parser.Parse(reader, null); Assert.IsNotNull(document); var sampleTestGeneratorProvider = new MsTestGeneratorProvider(new CodeDomHelper(CodeDomProviderLanguage.CSharp)); var converter = sampleTestGeneratorProvider.CreateUnitTestConverter(); CodeNamespace code = converter.GenerateUnitTestFixture(document, "TestClassName", "Target.Namespace"); Assert.IsNotNull(code); var featureSetupCall = code .Class() .Members() .Single(m => m.Name == "TestInitialize") .Statements .OfType <CodeConditionStatement>() .First() .TrueStatements .OfType <CodeExpressionStatement>() .First() .Expression .As <CodeMethodInvokeExpression>(); featureSetupCall.Should().NotBeNull(); featureSetupCall.Method.MethodName.Should().Be("FeatureSetup"); featureSetupCall.Method.TargetObject.As <CodeTypeReferenceExpression>().Type.Options.Should().Be(CodeTypeReferenceOptions.GlobalReference); } }
public void MsTestGeneratorShouldSetDescriptionCorrectlyWhenExampleSetIdentifierIsUsed() { SpecFlowGherkinParser parser = new SpecFlowGherkinParser(new CultureInfo("en-US")); using (var reader = new StringReader(SampleFeatureFileWithMultipleExampleSets)) { SpecFlowDocument document = parser.Parse(reader, null); Assert.IsNotNull(document); var sampleTestGeneratorProvider = new MsTestGeneratorProvider(new CodeDomHelper(CodeDomProviderLanguage.CSharp)); var converter = sampleTestGeneratorProvider.CreateUnitTestConverter(); CodeNamespace code = converter.GenerateUnitTestFixture(document, "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"); } }
protected override void CheckSemanticErrors(SpecFlowDocument specFlowDocument) { try { base.CheckSemanticErrors(specFlowDocument); } catch (SemanticParserException e) { if (ShouldIgnoreException(e)) { return; } throw; } catch (CompositeParserException e) { if (e.Errors.All(ShouldIgnoreException)) { return; } throw; } }
private void RunScenario(SpecFlowDocument gherkinDocument, Scenario scenario) { FeatureSetup(gherkinDocument); var scenarioInfo = new ScenarioInfo(scenario.Name, scenario.Tags.GetTags().ToArray()); ScenarioSetup(scenarioInfo); IEnumerable <SpecFlowStep> steps = scenario.Steps.Cast <SpecFlowStep>(); if (gherkinDocument.SpecFlowFeature.Background != null) { steps = gherkinDocument.SpecFlowFeature.Background.Steps.Cast <SpecFlowStep>().Concat(steps); } try { foreach (var step in steps) { Debug.WriteLine($"> Running {step.Keyword}{step.Text}"); ExecuteStep(step); } ScenarioCleanup(); // normally this is the point when the scenario errors are thrown } finally { ScenarioTearDown(); FeatureTearDown(); } }
public TestClassGenerationContext( IUnitTestGeneratorProvider unitTestGeneratorProvider, SpecFlowDocument document, CodeNamespace ns, CodeTypeDeclaration testClass, CodeMemberField testRunnerField, CodeMemberMethod testClassInitializeMethod, CodeMemberMethod testClassCleanupMethod, CodeMemberMethod testInitializeMethod, CodeMemberMethod testCleanupMethod, CodeMemberMethod scenarioInitializeMethod, CodeMemberMethod scenarioStartMethod, CodeMemberMethod scenarioCleanupMethod, CodeMemberMethod featureBackgroundMethod, bool generateRowTests) { UnitTestGeneratorProvider = unitTestGeneratorProvider; Document = document; Namespace = ns; TestClass = testClass; TestRunnerField = testRunnerField; TestClassInitializeMethod = testClassInitializeMethod; TestClassCleanupMethod = testClassCleanupMethod; TestInitializeMethod = testInitializeMethod; TestCleanupMethod = testCleanupMethod; ScenarioInitializeMethod = scenarioInitializeMethod; ScenarioStartMethod = scenarioStartMethod; ScenarioCleanupMethod = scenarioCleanupMethod; FeatureBackgroundMethod = featureBackgroundMethod; GenerateRowTests = generateRowTests; CustomData = new Dictionary <string, object>(); }
private void SerializeDocument(SpecFlowDocument feature, string fileName) { using (var writer = new StreamWriter(fileName, false, Encoding.UTF8)) { SerializeDocument(feature, writer); } }
private string SerializeDocument(SpecFlowDocument feature) { using (var writer = new Utf8StringWriter()) { SerializeDocument(feature, writer); return(writer.ToString()); } }
public new CodeNamespace GenerateUnitTestFixture(SpecFlowDocument document, string testClassName, string targetNamespace) { foreach (var scenario in document.SpecFlowFeature.ScenarioDefinitions) { } return(base.GenerateUnitTestFixture(document, testClassName, targetNamespace)); }
public CodeNamespace GenerateUnitTestFixture( SpecFlowDocument specFlowDocument, string testClassName, string targetNamespace) { var specFlowFeature = specFlowDocument.SpecFlowFeature; var flavors = GetFlavors(specFlowFeature.Tags).ToList(); // If the feature doesn't have any flavors, just invoke the feature generator. if (!flavors.Any()) { return(_featureGenerator.GenerateUnitTestFixture(specFlowDocument, testClassName, targetNamespace)); } // Create the range of flavor combinations. var combinations = CreateFlavorCombinations(flavors); var generatorResults = new List <CodeNamespace>(); foreach (var combination in combinations) { var clonedDocument = CreateFlavoredFeature(specFlowDocument, combination); string previousFormat = null; if (_featureGenerator is UnitTestFeatureGenerator unitTestFeatureGenerator) { previousFormat = unitTestFeatureGenerator.TestclassNameFormat; var extension = "_With" + string.Join( "_AndWith", combination.Select(combo => combo.Category + combo.Value)); unitTestFeatureGenerator.TestclassNameFormat += extension; } // Generate the flavored test fixture. var generatorResult = _featureGenerator.GenerateUnitTestFixture(clonedDocument, testClassName, targetNamespace); generatorResults.Add(generatorResult); if (previousFormat != null) { ((UnitTestFeatureGenerator)_featureGenerator).TestclassNameFormat = previousFormat; } } var result = generatorResults.First(); foreach (var generatorResult in generatorResults.Skip(1)) { foreach (CodeTypeDeclaration type in generatorResult.Types) { result.Types.Add(type); } } return(result); }
protected virtual void AcceptDocument(SpecFlowDocument document) { OnDocumentVisiting(document); if (document.Feature != null) { AcceptFeature(document.Feature); } OnDocumentVisited(document); }
protected CodeNamespace SetupFeatureGenerator <T>(SpecFlowDocument document, string testClassName = "TestClassName", string tagetNamespace = "Target.Namespace") where T : IUnitTestGeneratorProvider { var codeDomHelper = new CodeDomHelper(CodeDomProviderLanguage.CSharp); _unitTestGeneratorProvider = (T)Activator.CreateInstance(typeof(T), codeDomHelper, SampleFeatureFile.Variant); var featureGenerator = FeatureGenerator(codeDomHelper); return(featureGenerator.GenerateUnitTestFixture(document, testClassName, tagetNamespace)); }
private void SerializeDocument(SpecFlowDocument feature, TextWriter writer) { var oldFeature = CompatibleAstConverter.ConvertToCompatibleFeature(feature); oldFeature.SourceFile = null; XmlSerializer serializer = new XmlSerializer(typeof(Feature)); serializer.Serialize(writer, oldFeature); }
private IHasLocation ProcessScenarioDefinition(IHasLocation definition, SpecFlowDocument doc) { if (definition is ScenarioOutline outline) { return(outline.Clone(examples: outline.Examples.Select(e => HandleTags(e, doc)))); } return(definition); }
public void Should_not_pass_ignore_as_test_class_category() { var generator = CreateUnitTestFeatureGenerator(); SpecFlowDocument theDocument = ParserHelper.CreateDocument(new string[] { "ignore", "other" }); generator.GenerateUnitTestFixture(theDocument, "dummy", "dummyNS"); unitTestGeneratorProviderMock.Verify(ug => ug.SetTestClassCategories(It.IsAny <TestClassGenerationContext>(), It.Is <IEnumerable <string> >(cats => !cats.Contains("ignore")))); }
public void Should_support_case_insensitive_ignore_tag_on_scenario() { var generator = CreateUnitTestFeatureGenerator(); SpecFlowDocument theDocument = ParserHelper.CreateDocument(scenarioTags: new[] { "IgnoRe" }); generator.GenerateUnitTestFixture(theDocument, "dummy", "dummyNS"); unitTestGeneratorProviderMock.Verify(ug => ug.SetTestMethodIgnore(It.IsAny <TestClassGenerationContext>(), It.IsAny <CodeMemberMethod>())); }
public void Should_not_call_SetTestMethodIgnore_when_feature_ignored() { var generator = CreateUnitTestFeatureGenerator(); SpecFlowDocument theDocument = ParserHelper.CreateDocument(new string[] { "ignore" }); generator.GenerateUnitTestFixture(theDocument, "dummy", "dummyNS"); unitTestGeneratorProviderMock.Verify(ug => ug.SetTestMethodIgnore(It.IsAny <TestClassGenerationContext>(), It.IsAny <CodeMemberMethod>()), Times.Never()); }
public void Should_support_case_insensitive_ignore_tag_on_feature() { var generator = CreateUnitTestFeatureGenerator(); SpecFlowDocument theDocument = ParserHelper.CreateDocument(new string[] { "IgnoRe" }); generator.GenerateUnitTestFixture(theDocument, "dummy", "dummyNS"); unitTestGeneratorProviderMock.Verify(ug => ug.SetTestClassIgnore(It.IsAny <TestClassGenerationContext>())); }
public CodeNamespace GenerateUnitTestFixture(SpecFlowDocument specFlowDocument, string testClassName, string targetNamespace) { CodeNamespace result = null; bool onlyFullframework = false; var specFlowFeature = specFlowDocument.SpecFlowFeature; bool onlyDotNetCore = false; if (specFlowFeature.HasTags()) { if (specFlowFeature.Tags.Where(t => t.Name == "@SingleTestConfiguration").Any()) { return(_defaultFeatureGenerator.GenerateUnitTestFixture(specFlowDocument, testClassName, targetNamespace)); } onlyFullframework = HasFeatureTag(specFlowFeature, "@fullframework"); onlyDotNetCore = HasFeatureTag(specFlowFeature, "@dotnetcore"); } if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { onlyFullframework = false; onlyDotNetCore = true; } var tagsOfFeature = specFlowFeature.Tags.Select(t => t.Name); var unitTestProviders = tagsOfFeature.Where(t => _unitTestProviderTags.Where(utpt => string.Compare(t, "@" + utpt, StringComparison.CurrentCultureIgnoreCase) == 0).Any()); foreach (var featureGenerator in GetFilteredFeatureGenerator(unitTestProviders, onlyFullframework, onlyDotNetCore)) { var clonedDocument = CloneDocumentAndAddTag(specFlowDocument, featureGenerator.Key.UnitTestProvider); var featureGeneratorResult = featureGenerator.Value.GenerateUnitTestFixture(clonedDocument, testClassName, targetNamespace); if (result == null) { result = featureGeneratorResult; } else { foreach (CodeTypeDeclaration type in featureGeneratorResult.Types) { result.Types.Add(type); } } } if (result == null) { result = new CodeNamespace(targetNamespace); } return(result); }
public void Should_TagFilteredFeatureGeneratorProvider_not_be_applied_for_feature_with_no_tgas() { container.RegisterTypeAs <TestTagFilteredFeatureGeneratorProvider, IFeatureGeneratorProvider>("mytag"); SpecFlowDocument theDocument = ParserHelper.CreateAnyDocument(); var featureGeneratorRegistry = CreateFeatureGeneratorRegistry(); var generator = featureGeneratorRegistry.CreateGenerator(theDocument); generator.Should().NotBe(TestTagFilteredFeatureGeneratorProvider.DummyGenerator); }
public void Should_TagFilteredFeatureGeneratorProvider_applied_for_registered_tag_name_with_at() { container.RegisterTypeAs <TestTagFilteredFeatureGeneratorProvider, IFeatureGeneratorProvider>("@mytag"); SpecFlowDocument theDocument = ParserHelper.CreateAnyDocument(tags: new[] { "mytag" }); var featureGeneratorRegistry = CreateFeatureGeneratorRegistry(); var generator = featureGeneratorRegistry.CreateGenerator(theDocument); generator.Should().Be(TestTagFilteredFeatureGeneratorProvider.DummyGenerator); }
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) )); }
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); }
private static CodeNamespace GenerateCodeNamespaceFromFeature(string feature, bool parallelCode = false, string[] ignoreParallelTags = null) { CodeNamespace code; using (var reader = new StringReader(feature)) { SpecFlowGherkinParser parser = new SpecFlowGherkinParser(new CultureInfo("en-US")); SpecFlowDocument document = parser.Parse(reader, "test.feature"); var featureGenerator = CreateFeatureGenerator(parallelCode, ignoreParallelTags); code = featureGenerator.GenerateUnitTestFixture(document, "TestClassName", "Target.Namespace"); } return(code); }
public static Feature ConvertToCompatibleFeature(SpecFlowDocument specFlowDocument) { var specFlowFeature = specFlowDocument.SpecFlowFeature; return new Feature(specFlowFeature.Keyword, specFlowFeature.Name, ConvertToCompatibleTags(specFlowFeature.Tags), specFlowFeature.Description, ConvertToCompatibleBackground(specFlowFeature.Background), ConvertToCompatibleScenarios(specFlowFeature.ScenarioDefinitions), ConvertToCompatibleComments(specFlowDocument.Comments)) { FilePosition = ConvertToCompatibleFilePosition(specFlowFeature.Location), Language = specFlowFeature.Language, SourceFile = specFlowDocument.SourceFilePath }; }
public static Feature ConvertToCompatibleFeature(SpecFlowDocument specFlowDocument) { var specFlowFeature = specFlowDocument.SpecFlowFeature; return(new Feature(specFlowFeature.Keyword, specFlowFeature.Name, ConvertToCompatibleTags(specFlowFeature.Tags), specFlowFeature.Description, ConvertToCompatibleBackground(specFlowFeature.Background), ConvertToCompatibleScenarios(specFlowFeature.ScenarioDefinitions), ConvertToCompatibleComments(specFlowDocument.Comments)) { FilePosition = ConvertToCompatibleFilePosition(specFlowFeature.Location), Language = specFlowFeature.Language, SourceFile = specFlowFeature.SourceFilePath }); }
public static FeatureMetadata GetFeatureMetadata(SpecFlowDocument document) { var metadata = new FeatureMetadata(); var lines = File.ReadAllLines(document.SourceFilePath); metadata._isFeatureIgnored = ContainsAttribute(lines, document.Feature.Location, 0, IgnoreFeature); int previousElementLine = document.Feature.Location.Line; if (document.SpecFlowFeature.Background != null) { foreach (Step backgroundStep in document.SpecFlowFeature.Background.Steps) { bool isIgnoredStep = ContainsAttribute(lines, backgroundStep.Location, previousElementLine, IgnoreStep); if (isIgnoredStep) { metadata._ignoredSteps.Add(backgroundStep); } previousElementLine = backgroundStep.Location.Line; } } foreach (Scenario scenario in document.SpecFlowFeature.Children.OfType <Scenario>()) { bool isIgnoredScenario = ContainsAttribute(lines, scenario.Location, previousElementLine, IgnoreScenario); if (isIgnoredScenario) { metadata._ignoredScenarios.Add(scenario); } previousElementLine = scenario.Location.Line; foreach (Step step in scenario.Steps) { bool isIgnoredStep = ContainsAttribute(lines, step.Location, previousElementLine, IgnoreStep); if (isIgnoredStep) { metadata._ignoredSteps.Add(step); } previousElementLine = step.Location.Line; } } return(metadata); }