9

I have two classes (class A and B) both marked with [Binding]. Currently I'm using a class per feature. Classes A and B both have a step that looks like this:

   [Given(@"an employee (.*) (.*) is a (.*) at (.*)")]
   public void GivenAnEmployeeIsAAt(string firstName, string lastName, string role, string businessUnitName)

When I run the scenario for the features defined in class A, and the test runner executes the step indicated above, the matching step in class B gets executed instead.

Are "Steps" global as well? I thought only the "hook" methods are global, i.e. BeforeScenario, AfterScenario. I do not want this behavior for "Given", "Then", and "When". Is there any way to fix this? I tried putting the two classes in different namespaces and this didn't work either.

Also, am I potentially misusing SpecFlow by wanting each "Given" to be independent if I put them in separate classes?

SideFX
  • 839
  • 1
  • 12
  • 34

1 Answers1

14

Yes Steps are (per default) global. So you will run into trouble if you define two attributes that have RegExps that matches the same Step. Even if they are in separate classes.

Being in separate classes, or other placement (other assembly even) doesn't have anything to do with how SpecFlow groups it - it's just a big list of Given's, When's and Then's that it try to match the Step against.

But there's a feature called Scoped Steps that solves this problem for you. Check it out here: https://github.com/techtalk/SpecFlow/blob/master/Tests/FeatureTests/ScopedSteps/ScopedSteps.feature

The idea is that you put another attribute (StepScope) on your Step Defintion method and then it will honor that scoping. Like this for example:

[Given(@"I have a step definition that is scoped to tag (?:.*)")]
[StepScope(Tag = "mytag")] 
public void GivenIHaveAStepDefinitionThatIsScopedWithMyTag()
{
    stepTracker.StepExecuted("Given I have a step definition that is scoped to tag 'mytag'");
}

... or to scope an entire step definition class to a single feature:

[Binding]
[StepScope(Feature = "turning on the light should make it bright")]
public class TurningOnTheLightSteps
{
    // ...
}

This step definition is using a StepScope for a tag. You can scope your steps by:

  • Tag
  • Scenario title
  • Feature title

Great question! I hadn't fully understood what that was for until now ;)

cfeduke
  • 23,100
  • 10
  • 61
  • 65
Marcus Hammarberg
  • 4,762
  • 1
  • 31
  • 37
  • Excellent, I was working with SpecFlow this morning, found this question, and figured I would need the answer later today - which I did. – cfeduke Mar 28 '11 at 21:07
  • So I guess if my problem is trying to organize the steps, which I am currently doing in classes (by feature), then the more appropriate organization would be by behavior. This way a collections of behavior can be gradually constructed and referred to later for reuse. Wonder if there is a TestDox-like tool for SpecFlow? – SideFX Mar 29 '11 at 00:14
  • Yes you're probably better off to organize your step definitions per logical entity (or better put behavior). I've created an example of that, that you might find useful. Check it out here: http://www.marcusoft.net/2011/01/kanbanboards-part-iitwo-step-forward.html?m=0 – Marcus Hammarberg Mar 29 '11 at 08:55
  • 1
    The link and syntax have changed a bit since the answer was originally posted. The new link is https://github.com/techtalk/SpecFlow/wiki/Scoped-Bindings and it shows the new syntax. – Ecyrb Dec 08 '11 at 20:52