Two types in SpecFlow; ScenarioContext and FeatureContext

Posted by Marcus Hammarberg on March 26, 2011
Stats
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 are 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.
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 are 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. You can find the code here.

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.

marking steps as pending

step defintions with pending

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.

Darren Cauthon has done a video on that and written about it on the SpecFlow wiki. Here is my example on that:

scenario for storing in dictionary

storing and retriving via typesafe extensions

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:

feature for scenarioInfo

title and tags from scenarioinfo

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:

feature for test error


using test error to log

This is another example (which was the way I looked into this in the first place):

using mvccontrib to capture failing screen

Here I am using MvcContrib to capture the screen of the failing test, and naming the screen shot after the title of the Scenario. So by combining the use of hooks and the knowledge of ScenarioContext when can do some interesting stuff, don’t you think?

ScenarioContext.Current.CurrentScenarioBlock

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

current scenarioblock feature

current scenarioblock stepdefinition

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.

The code for my FeatureContext scenarios is here.

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:

featureInfo scenario

step definition for featureinfo

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.

I hope you learned something. I sure did Winking smile. The code is here.


Published by Marcus Hammarberg on Last updated