SpecFlow – data driven testing

Nie jest to pierwszy wpis o SpecFlow i podstawy framework’a znajdziecie oczywiście  w archiwum.

W SpecFlow można definiować tzw. “Scenario outline”, które służą jako szablony dla testów. Oczywiście data-driven testing nie powinno być nadużywane i w szczególności dla acceptance tests nie ma to wielkiego sensu. SpecFlow jest często używany dla testów systemowych i UI, gdzie nie testujemy wszystkich możliwych kombinacji danych wejściowych.

Czasami jednak chcemy mieć bardziej sparametryzowany zestaw testów i tutaj  warto zastanowić się nad Scenario Outline.

Przykład (z oficjalnej dokumentacji):

Scenario Outline: eating Given there are <start> cucumbers When I eat <eat> cucumbers Then I should have <left> cucumbers Examples: | start | eat | left | | 12 | 5 | 7 | | 20 | 5 | 15 |

Jest to odpowiednik TestCase w przypadku czystego nUnit. Jeśli zajrzymy do code-behind, faktycznie zobaczymy, że to klasyczny data-driven test, który zawiera atrybuty TestCase:

[NUnit.Framework.TestAttribute()] [NUnit.Framework.DescriptionAttribute("eating")] [NUnit.Framework.TestCaseAttribute("12", "5", "7", null)] [NUnit.Framework.TestCaseAttribute("20", "5", "15", null)] public virtual void Eating(string start, string eat, string left, string[] exampleTags) { TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("eating", exampleTags); #line 6 this.ScenarioSetup(scenarioInfo); #line 7 testRunner.Given(string.Format("there are {0} cucumbers", start), ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); #line 8 testRunner.When(string.Format("I eat {0} cucumbers", eat), ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); #line 9 testRunner.Then(string.Format("I should have {0} cucumbers", left), ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); #line hidden this.ScenarioCleanup(); }

Powyższy scenariusz zostanie zatem wykonany dwukrotnie dla różnych zestawów danych.  Wygenerowane kroki wyglądają następująco:

[Binding] public class SampleScenarioSteps { [Given(@"there are (.*) cucumbers")] public void GivenThereAreCucumbers(int p0) { ScenarioContext.Current.Pending(); } [When(@"I eat (.*) cucumbers")] public void WhenIEatCucumbers(int p0) { ScenarioContext.Current.Pending(); } [Then(@"I should have (.*) cucumbers")] public void ThenIShouldHaveCucumbers(int p0) { ScenarioContext.Current.Pending(); } }

Jeszcze raz podkreślam, aby być ostrożnym z używaniem tego – często nie są testy jednostkowe. Z drugiej jednak strony, SpecFlow może być wykorzystywany dla klasycznych testów jednostkowych, pisanych bardziej w stylu BDD. W takiej sytuacji wciąż chcemy przetestować różne kombinacje i nic nie stoi na przeszkodzie, aby użyć ScenarioOutline. W końcu SpecFlow to nie tylko UI i acceptance testing.

Leave a Reply

Your email address will not be published.