Specflow测试步骤继承导致“步骤定义不明确”

本文关键字:定义 不明确 测试 继承 Specflow | 更新日期: 2023-09-27 18:19:10

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

[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
    }
}

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

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

TechTalk.SpecFlow.BindingException: Ambiguous step definitions found for step
'Given there is a customer': 
CustomerTestBase.GivenThereIsACustomer(Table),   
CustomerTestBase.GivenThereIsACustomer(Table)
谁能告诉我怎么解决这个问题?

Specflow测试步骤继承导致“步骤定义不明确”

现在我自己也想明白了,所以有几个注意事项(希望将来有人可以使用这个):

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

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

在运行时,SpecFlow通过全局扫描所有公共类寻找具有匹配[Given]属性的方法来找到要调用的方法。这意味着您不能对同一个Given there is a customer语句有两个不同的实现,如果您认为这是一个相当明智的设计决策,将减少歧义。

这对我来说很有效:

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是处理之间连接的工具。Feature 文件和.cs文件。这不是处理抽象的工具。如果我们需要任何类型的抽象或结构来防止重复或任何其他设计问题,我们可以单独创建它。

如果你认为Specflow是一个绑定工具,我相信你不会寻找一种方法来处理你的抽象使用它。

例如,定义一个抽象的CustomerService

public abstract class CustomerService
{
   public abstract void Handle();
}