Specflow - Advanced topics
Scoped Bindings
Bindings (step definitions, hooks) are global for the entire SpecFlow project. This means that a step definition that is bound to a very generic step text, like When I save the changes becomes challenging to implement. The general solution for this problem is to phrase the scenarios in a way that the steps are phrased in a way that the usage context can be extracted from them (e.g. When I save the book details).
In some cases however, it is necessary to restrict the appliance of a step definition or hook based on certain conditions. This feature of SpecFlow can be used for this purpose.
Be careful! Coupling your step definitions to the features is an anti-pattern. Read more about it on the Cucumber Wiki
The scoped bindings can restrict the execution for
- feature (by feature title)
- scenario (by scenario title)
- tag
The scope can be defined with the [Scope] attribute. (Prior to v1.8, scopes has to be specified with the [StepScope]attribute.)
[Scope(Tag = "mytag", Feature = "feature title", Scenario = "scenario title")]
Hooks
The hooks (event bindings) can be used to perform additional automation logic on specific events, such as before executing a scenario.
Hooks are global, but can be restricted to run only for features or scenarios with a specific tag (see below). The execution order of hooks for the same event is undefined.
SUPPORTED HOOK ATTRIBUTES
Attribute | Tag filtering | Description |
---|---|---|
[BeforeTestRun] [AfterTestRun] |
- |
Automation logic that has to run before/after the entire test run |
[BeforeFeature] [AfterFeature] |
+ |
Automation logic that has to run before/after executing each feature |
[BeforeScenario] or [Before] [AfterScenario] or [After] |
+ |
Automation logic that has to run before/after executing each scenario or scenario outline example |
[BeforeScenarioBlock] [AfterScenarioBlock] |
+ |
Automation logic that has to run before/after executing each scenario block (e.g. between the "givens" and the "whens") |
[BeforeStep] [AfterStep] |
+ |
Automation logic that has to run before/after executing each scenario step |
You can annotate a single method with multiple attributes.
HOOK EXECUTION ORDER
By default the hooks of the same type (e.g. two [BeforeScenario] hook) are executed in an unpredictable order. If you need to ensure a specific execution order, you can specify the Order property for the hook attributes.
[BeforeScenario(Order = 0)] public void CleanDatabase() { // we need to run this first } [BeforeScenario(Order = 100)] public void LoginUser() { // we can perform login based on a clean database }
The value provided for the order attribute specifies the order, not the priority, ie. the hook with the lower number always executed earlier both for before and after hooks.
If no order is specified, the default order of 1000 is used. It is not recommended to depend on this default value though.
TAG SCOPING
Most of the hooks support tag scoping. This means that they are executed only if the feature or the scenario has at least one of the tags specified in the tag filter (tags are combined with OR). You can specify the tag in the attribute or usingScoped Bindings (from v1.8).
The following example starts Selenium for scenarios marked with the @web tag.
[BeforeScenario("web")] public static void BeforeWebScenario() { StartSelenium(); }
For the scenario, scenarioblock or step hooks, the following tags are considered:
- tags defined for the feature
- tags defined for the scenario
- tags defined for the scenario outline
- tags defined for the scenario outline example set (Examples:)
You can define more complex filters using the ScenarioContext class. The following example starts selenium if the scenario is tagged with @web and @automated.
[BeforeScenario("web")] public static void BeforeWebScenario() { if(ScenarioContext.Current.ScenarioInfo.Tags.Contains("automated")) StartSelenium(); }