Tak, można utworzyć globalne metody PrzedScenariusz i AfterScenario, ale w praktyce okazało się, że nie jest to pożądane, ponieważ zwykle takie same przed i po krokach nie mają zastosowania do kroków w projekcie testowym.
Zamiast tego, tworzę klasę podstawową dla moich definicji kroków, które miałyby metody PrzedScenariusz i AfterScenarios, które chciałbym zastosować do wszystkich moich scenariuszy, np.
public class BaseStepDefinitions
{
[BeforeScenario]
public void BeforeScenario()
{
// BeforeScenario code
}
[AfterScenario]
public void AfterScenario()
{
// AfterScenario code
}
}
Należy zauważyć, że nie użyłem atrybutu Powiązanie dla tej klasy. Jeśli to uwzględnisz, kroki BeforeScenario i AfterScenario będą globalne.
Następnie wyprowadzam moje klasy definicji kroków z tej klasy definicji kroku podstawowego, aby miały one metody scenariusza Przed i Po, np.
[Binding]
public class SpecFlowFeature1Steps : BaseStepDefinitions
{
[Given(@"I have entered (.*) into the calculator")]
public void GivenIHaveEnteredIntoTheCalculator(int inputValue)
{
ScenarioContext.Current.Pending();
}
[When(@"I press add")]
public void WhenIPressAdd()
{
ScenarioContext.Current.Pending();
}
[Then(@"the result should be (.*) on the screen")]
public void ThenTheResultShouldBeOnTheScreen(int expectedResult)
{
ScenarioContext.Current.Pending();
}
}
Podczas gdy takie podejście nie ma charakteru globalnego, dzięki wprowadzeniu wszystkich definicji Etapu z klasy BaseStepDefinition osiągamy ten sam wynik.
Daje również większą kontrolę, tj. Jeśli nie chcesz wiązania wiązania BeforeScenario lub AfterScenario, nie wyprowadzaj go z kroków podstawowych.
Niestety to nie działa. Jak tylko zaczniesz korzystać z wielu klas Binding, otrzymasz wiele połączeń. Na przykład, jeśli mogę przedłużyć powyższy przykład podzielić na trzy klasy wiązań,
[Binding]
public class SpecFlowFeature1Steps : BaseStepDefinitions
{
[Given(@"I have entered (.*) into the calculator")]
public void GivenIHaveEnteredIntoTheCalculator(int inputValue)
{
//ScenarioContext.Current.Pending();
}
}
[Binding]
public class SpecFlowFeature2Steps : BaseStepDefinitions
{
[When(@"I press add")]
public void WhenIPressAdd()
{
//ScenarioContext.Current.Pending();
}
}
[Binding]
public class SpecFlowFeature3Steps : BaseStepDefinitions
{
[Then(@"the result should be (.*) on the screen")]
public void ThenTheResultShouldBeOnTheScreen(int expectedResult)
{
//ScenarioContext.Current.Pending();
}
}
public class BaseStepDefinitions
{
[BeforeScenario]
public void BeforeScenario()
{
// BeforeScenario code
Console.WriteLine("Before. [Called from "+ this.GetType().Name+"]");
}
[AfterScenario]
public void AfterScenario()
{
// AfterScenario code
Console.WriteLine("After. [Called from " + this.GetType().Name + "]");
}
}
Wtedy, kiedy go uruchomić, wyjście jest
Before. [Called from SpecFlowFeature1Steps]
Before. [Called from SpecFlowFeature2Steps]
Before. [Called from SpecFlowFeature3Steps]
Given I have entered 50 into the calculator
-> done: SpecFlowFeature1Steps.GivenIHaveEnteredIntoTheCalculator(50) (0.0s)
And I have entered 70 into the calculator
-> done: SpecFlowFeature1Steps.GivenIHaveEnteredIntoTheCalculator(70) (0.0s)
When I press add
-> done: SpecFlowFeature2Steps.WhenIPressAdd() (0.0s)
Then the result should be 120 on the screen
-> done: SpecFlowFeature3Steps.ThenTheResultShouldBeOnTheScreen(120) (0.0s)
After. [Called from SpecFlowFeature1Steps]
After. [Called from SpecFlowFeature2Steps]
After. [Called from SpecFlowFeature3Steps]
AlSki i Truan mają rację, ta odpowiedź nie działa zgodnie z oczekiwaniami. Nie akceptuj tego i zaakceptuj Alkskiego, a ja usunę odpowiedź. –