📜 ⬆️ ⬇️

Data Driven Tests & SpecFlow

SpecFlow allows you to use embedded tables for data driven scripts. In my practice, I ran into two problems with this approach:
  1. Sometimes you want, on the contrary, to get auto-documentation from the test (for example, API testing)
  2. When the amount of data is large, it is better to store it somewhere else (often use Excel for Acceptance Test Cases)

Having rummaged in the Gesigner Generated code, I was able to solve both problems.

Let's write a base class for tests that won't use DSL


[TestFixture] public class DslGenerationTestsBase : TestsBase { private static ITestRunner _testRunner; [TestFixtureSetUp] public virtual void FeatureSetup() { _testRunner = TestRunnerManager.GetTestRunner(); var features = GetType().GetCustomAttributes(typeof (FeatureAttribute), false); if (!features.Any()) { throw new ConfigurationErrorsException("Feature Attribute is required"); } var feature = (FeatureAttribute)features.Single(); var featureInfo = new FeatureInfo( new System.Globalization.CultureInfo("en-US"), feature.Title, feature.Story, ProgrammingLanguage.CSharp, null); _testRunner.OnFeatureStart(featureInfo); } [TestFixtureTearDown] public virtual void FeatureTearDown() { _testRunner.OnFeatureEnd(); _testRunner = null; } [TearDown] public virtual void TearDown() { _testRunner.OnScenarioEnd(); } protected void ScenarioSetup(ScenarioInfo scenarioInfo) { _testRunner.OnScenarioStart(scenarioInfo); } protected void ScenarioCleanup() { _testRunner.CollectScenarioErrors(); } protected void Given(string given, string keyword = "Given ") { _testRunner.Given(given, null, null, keyword); } protected void When(string when, string keyword = "When ") { _testRunner.When(when, null, null, keyword); } protected void Then(string then, string keyword = "Then ") { _testRunner.Then(then, null, null, keyword); } } 

In order to describe the Feature in a declarative style, we write our own attribute. We use NUnit. In order for Feature to appear in a report, you must use DescriptionAttribute. Therefore, we will inherit our attribute from it.

 [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public class FeatureAttribute : DescriptionAttribute { public string Title { get; private set; } public string Story { get; private set; } public CultureInfo CultureInfo { get; private set; } public FeatureAttribute(string title, string story):base(title) { Title = title; Story = story; CultureInfo = new CultureInfo("en-US"); } public FeatureAttribute(string title, string story, CultureInfo cultureInfo) : base(title) { Title = title; Story = story; CultureInfo = cultureInfo; } } 

And write a class with dough


Instead of TestCase, you can use TestCaseSource and read data from any source.
')
 [Binding] [Feature("DslGeneration", "In order to avoid silly mistakes\n" + "As a math idiot\n" + "I want to be told the sum of two numbers")] [Category("Examples")] public class DataDrivenDslGenerationExample : DslGenerationTestsBase { private decimal _a; private decimal _b; [TestCase("1", "2", "3")] [TestCase("2", "3", "5")] public void CodeSomeTest_DslIsGenerated(string a, string b, string c) { var scenarioInfo = new ScenarioInfo("DslGeneration Outline", null); ScenarioSetup(scenarioInfo); Given("Calculator is on"); When(string.Format("User fill {0} and {1}", a, b)); Then(string.Format("{0} is returned", c)); ScenarioCleanup(); } [Given(@"Calculator is on")] public void CalculatorIsOn() { } [When(@"User fill (.*) and (.*)")] public void Fill(int a, int b) { _a = a; _b = b; } [Then(@"(.*) is returned")] public void ResultReturned(int c) { var actual = _a + _b; Assert.AreEqual(c, actual); } } 

If your base class is in a different assembly, you will need to add it to the configuration:
 <specFlow> <stepAssemblies> <stepAssembly assembly="..." /> </stepAssemblies> <!-- For additional details on SpecFlow configuration options see http://go.specflow.org/doc-config --> </specFlow> 

That's all, now with the help of SpecFlow.exe you can generate a beautiful report




Thus, you can create auto-documentation for APIs and scripts with a lot of data.

Source: https://habr.com/ru/post/181311/


All Articles