Specflow test step inheritance causes "Ambiguous step definitions"

specflow reuse steps
specflow scope
specflow manual test
specflow scenario context
specflow update step definition
scenario injection specflow
specflow get scenario tags
specflow binding

I want to have the following test step class structure:

[Binding]
public class BaseStep
{
    [Given(@"there is a customer")]
    public void GivenThereIsACustomer(Table table)
    {
        HandleCustomer(table);
    }

    protected virtual void HandleCustomer(Table table)
    {
    }
}

[Binding]
public class FeatureOneStep : BaseStep
{
    protected override void HandleCustomer(Table table)
    {
         // feature one action
    }

    [Given(@"feature one specific step")]
    public void GivenFeatureOneSpecificAction(Table table)
    {
        // do something
    }

}

[Binding]
public class FeatureTwoStep : BaseStep
{
    protected override void HandleCustomer(Table table)
    {
         // feature two action
    }

    [Given(@"feature two specific step")]
    public void GivenFeatureTwoSpecificAction(Table table)
    {
        // do something
    }
}

"Given there is a customer" is a common step that is used in both FeatureOne and FeatureTwo, but it will have different handling logic inside the two features. So I decide to put this step definition into a base class and override the protected methods in two derived classes respectively.

However, when I ran the tests, I have the following error:

TechTalk.SpecFlow.BindingException: Ambiguous step definitions found for step
'Given there is a customer': 
CustomerTestBase.GivenThereIsACustomer(Table),   
CustomerTestBase.GivenThereIsACustomer(Table)

Can any one tell me how to fix this issue?

Specflow test step inheritance causes ", however, when ran tests, have following error: techtalk.specflow.​bindingexception: ambiguous step definitions found step 'given there  Working with SpecFlow Tables and SpecFlow.Assist (Chapter 5) In the previous article , you’ve seen a number of ways to make individual steps in SpecFlow more expressive. This helps you create steps and scenarios that are highly readable and close to the business domain language that is spoken in your organization.

The answer is simple; Don't use inheritance to define your bindings.

At run time SpecFlow finds its methods to call by scanning globally across all public classes looking for methods with matching [Given] attributes. This means that you can't have two different implementations for the same Given there is a customer statement, which if you think about it is quite a sensible design decision that will reduce ambiguity.

Ambiguous step definition with step inheritance in new version of , I have a problem with step inheritance in my project. The structure is: I have a base test library which I use as a NuGet package, I guess something has changed in SpecFlow that pushes the idea of NOT using step inheritance even further. What makes it harder in my case, all my 3 projects may be used  For sharing state across multiple step definition classes, context injection provides a much better solution, which does not suffer from the inheritance issues. Conclusion. Step definitions are global in SpecFlow granting you the possibility to split larger step definition classes to smaller ones.

This worked well for me :

public class BaseSteps
{
    [Given(@"Method called")]
    public virtual void WhenMethodCalled()
    {

    }
}    



[Binding]
[Scope(Feature= "specific_feature")
public class DerivedSteps : BaseSteps
{
    [Given(@"Method called")]
    [Scope(Feature= "specific_feature", Tag ="specific_tag")]
    public override void WhenMethodCalled()
    {

    }
}

SpecFlow tips: Problems with placing step definitions to base , Step definitions and other bindings are global in SpecFlow. scope the “foo” step inherited from the base class, so the test will pass and is not  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.

SpecFlow Tips: Baseclass or Context Injection, Step definitions are global in SpecFlow, just like in any other Use static fields (​this will cause troubles if later you want to run your tests in parallel); Use the inherited into your derived step definition classes; when SpecFlow  The reason for this is the following: if you declare an instance field in the base class, it will be inherited into your derived step definition classes; when SpecFlow creates instances of them, each will have its own field, so basically they will not “see” the data of each other.

Specflow test step inheritance causes “Ambiguous step definitions , I want to have the following test step class structure: [Binding] public class BaseStep { [Given(@"there is a customer")] public void GivenThereIsACustomer(​Table  Welcome to the SpecFlow documentation. If you are new to SpecFlow, we recommend that you start out by following our dedicated Getting Started guide first.

Troubleshooting - SpecFlow Documentation - SpecFlow, The SpecFlow Visual Studio integration caches the binding status of step The Visual Studio Test Adapter cache may also get corrupted, causing tests to not be​  I have a problem with step inheritance in my project. The structure is: I have a base test library which I use as a NuGet package, and I have 3 other test projects in which I use it. Base library has BasicSteps.cs marked with [Binding] attribute, all project step files are inherited from this file.

Comments
  • This is the right answer. I understand that SpecFlow doesn't want us using inheritance, but it seems to me to be an unnecessarily confusing design choice. Object oriented programming techniques already provides powerful methods of code reuse. Why reinvent the wheel?
  • He's right. Inheritance only works if you control the initialization. Since the test is auto-generated, you can't define which concrete class will be used.
  • You could write a step that does the construction and then calls the subclass if you're stuck on using inheritance. 1 - BaseClass bc = FeatureOneClass(); and 2 - bc.featureonestep;
  • If the base class is abstract, I believe this reasoning does not apply. SpecFlow should only ever be interested in concrete classes, but it would seem that it scans too loosely.