2

I have implemented code in following fashion.

public abstract class BaseDocumentStep<T> where T : class, new()
{
    protected T _document;

    [Given(@"I Add New '(.*)'")]
    public void GivenIAddNew(string p0)
    {
        Console.WriteLine(p0);
    }

}

[Binding]
public class CustomerSteps : BaseDocumentStep<Customer> 
{

}

[Binding]
public class EmployeeSteps : BaseDocumentStep<Employee>
{

}

Feature Files :- a) Customer Feature

Scenario: Add New Customer
Given I Add New 'Customer'

b) Employee Feature

 Scenario: Add New Employee
Given I Add New 'Employee'

When I run these scenarios. I got following error :

-> binding error: Ambiguous step definitions found for step 'Given I Add New 'Customer'': BaseDocumentStep1.GivenIAddNew(String), BaseDocumentStep1.GivenIAddNew(String) After Scenario

I am not able to figure out, why specflow consider this step as ambiguous ?

Thanks in Advance. Adi.

user2266837
  • 587
  • 2
  • 5
  • 12

2 Answers2

0

Adi,

Are there any reasons you want to use the abstract class for your tests? I have been using specflow for a few years now, and I have always tried to keep them simple and linear. Can you try to replace your step definition file with this:

[Binding]
public class EmployeeSteps
{
    [Given(@"I Add New '(.*)'")]
    public void GivenIAddNew(string p0)
    {
        Console.WriteLine(p0);
    }
}

this is working fine for me. This should work out fine unless you have other reasons not to keep your steps this simple.

Leibniz
  • 184
  • 1
  • 5
  • Thanks Leibniz for the reply. Yes there is a reason to use abstract class. Application is a legacy application and implemented using MVP pattern. We are doing testing of presentation layer using specflow. So we have some common steps but there save process depends upon the type of object we passed. That's why we have used abstract class. e.g Base User is abstract class. NormalUser inherits Base User, Super User also inherits base user like this. – user2266837 Jul 30 '16 at 20:02
0

The problem here is that in Specflow all steps are global, and so if you declare a step in a base class, that step is also declared in every derived class. So you get one instance of

[Given(@"I Add New '(.*)'")]
public void GivenIAddNew(string p0)
{
    Console.WriteLine(p0);
}

in CustomerSteps and EmployeeSteps

Step binding methods should not be declared in base classes, the steps will always be able to be found due to the fact that they are global.

It's not exactly clear what you want to achieve with your generic design, but perhaps if you give a bit more information about that (probably another question is better) then we might be able to help you get to a solution that does not require inheritance with binding classes.

Sam Holder
  • 32,535
  • 13
  • 101
  • 181
  • [this answer](http://stackoverflow.com/a/31577410/97614) may provide an option to continue to use inheritance, but be aware that due to issues in the current VS extension using scopes can cause issues navigating to steps – Sam Holder Jul 27 '16 at 07:41