Specflow测试步骤继承导致"不明确的步骤定义"

wd1*_*113 12 c# inheritance acceptance-testing ambiguous specflow

我想拥有以下测试步骤类结构:

[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
    }
}
Run Code Online (Sandbox Code Playgroud)

"鉴于有客户"是FeatureOne和FeatureTwo中使用的常见步骤,但它在两个功能中将具有不同的处理逻辑.因此,我决定将此步骤定义放入基类中,并分别覆盖两个派生类中的受保护方法.

但是,当我运行测试时,我有以下错误:

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

谁能告诉我如何解决这个问题?

Run*_*ipe 18

现在我自己想出这个,所以有几个笔记(希望有人可以在将来使用它):

  • 不要在基类上包含[Binding]属性
  • 为每个要素文件创建派生类
    • 将[Binding]属性添加到派生类(将自动包括基类中的所有步骤定义)
    • 将[Scope]属性添加到派生类; 指定命名参数功能的功能名称

  • 这是正确的答案.我知道SpecFlow不希望我们使用继承,但在我看来,这似乎是一个不必要的令人困惑的设计选择.面向对象的编程技术已经提供了强大的代码重用方法.为什么重新发明轮子? (7认同)

AlS*_*Ski 12

答案很简单; 不要使用继承来定义绑定.

在运行时,SpecFlow通过在所有公共类中全局扫描来查找其方法,以查找具有匹配[Given]属性的方法.这意味着您不能为同一Given there is a customer语句提供两种不同的实现,如果您认为这是一个非常明智的设计决策,将减少歧义.


小智 7

这对我很有效:

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()
    {

    }
}
Run Code Online (Sandbox Code Playgroud)