Powered By Blogger

Search Here!

Sunday, July 1, 2012

SpecFlow: ScenarioContext and FeatureContext !

Two types in SpecFlow; ScenarioContext and FeatureContext
The other day I got the opportunity to try to figure out some elaborative error handling with SpecFlow and had to check up the ScenarioContext a bit closer. It turns out that there is some stuff on it that can be useful from time to time. And that it was a FeatureContext object as well.
This post looks a bit closer on these to guys and gives some tips on how you might want to use them in your code.
ScenarioContext
Most of us has at least seen the ScenarioContext from the the code that SpecFlow generates when a missing step definition is found:
[Binding]
public class StepDefinitions
{
    [Then(@"I don't have this step definition in place yet")]
    public void ThenIDonTHaveThisStepDefintionInPlaceYet()
    {
        ScenarioContext.Current.Pending();
    }
}
But there are some other interesting stuff you can do with and get from that object. I’ve tried to write scenarios that show that off. 

ScenarioContext.Pending

Well – this method is known to most of us, as I said. This is default behavior for a missing step definition, but you can also use it directly if (why?) you want to.

ScenarioContext.Current

This is a very useful feature of the ScenarioContext that helps you to store values in a Dictionary between the steps. This helps you to organize your step definitions better that if you would use private variables in the step definition class.
There are some type safe extension methods that helps you to get values in and out of the dictionary in a safer way. To get that you need to include the namespace TechTalk.SpecFlow.Assist, since they are extension methods on the ScenarioContext.

ScenarioContext.ScenarioInfo

You can also get hold of some information about the scenario you’re executing right now. For example the title and the tags of it:

More interesting maybe is the ability to check if an error has occurred. That’s done with the ScenarioContext.Current.TestError property, which simply is the exception that has occurred.
You can use that to do some interesting “error handling” as I told you above. Here is an un-interesting version:

ScenarioContext.Current.CurrentScenarioBlock
You can also get hold of the “type” of step you’re on (Given, When or Then) which is pretty cool, but I cannot see and immediate use of it.

FeatureContext

There is a FeatureContext as well. The difference of course is that the FeatureContext exists during the execution of the complete feature while the ScenarioContext only exists during a scenario.

FeatureContext.Current

FeatureContext also have a Current property which holds a Dictionary. But I works in exactly the same way as the ScenarioContext.Current so I won’t go into details of it. It’s actually implemented with the same class SpecFlowContext so it IS the same behavior.

FeatureContext.FeatureInfo

The FeatureInfo is a bit more elaborative than the ScenarioInfo, but it works in the same manner:
Also I should mention here that FeatureContext exposes a Binding Culture property that simply points to the culture the feature is written in (en-US in our example).

Conclusion – what is this good for?

So now that we know about this – what is it good for?
For me this kind of information can be most useful combined with the use of Hooks so that you can get better logging, better tracing and more customized logging of the execution of your scenarios.

No comments:

Post a Comment