SpecFlow步骤的布尔参数

本文关键字:布尔 参数 SpecFlow | 更新日期: 2023-09-27 18:10:47

在SpecFlow中,我想检查步骤定义中是否存在字符串,目前我正在做笨拙的事情,就像这个人为的例子:

[Given(@"Foo ( bar)?")]
public void GivenFoo(string bar)
{
    if (bar == " bar")
    {
        // do bar
    }
}

但是,我想这样做:

[Given(@"Foo ( bar)?")]
public void GivenFoo(bool bar)
{
    if (bar)
    {
        // do bar
    }
}

但是我不知道怎么做,所以这是可能的吗?如果是的话,怎么做?

SpecFlow步骤的布尔参数

您绝对可以使用StepArgumentTransformation方法来做这种事情。您仍然需要编写解析器逻辑,但是您可以将其隔离到一个方法中,该方法的唯一目的是执行解析。

示例特征文件:

Feature: I win if I am Batman
Scenario: Happy
    Given I am the Batman
    Then I defeat the Joker
Scenario: Sad
    Given I am not the Batman
    Then I am defeated by the Joker

Specflow Bindings (c#):

[Binding]
public class IWinIfIAmBatmanFeature
{
    private bool iAmBatman;
    [StepArgumentTransformation(@"(am ?.*)")]
    public bool AmToBool(string value)
    {
        return value == "am";
    }
    [Given(@"I (.*) the Batman")]
    public void WhoAmI(bool amIBatman)
    {
        iAmBatman = amIBatman;
    }
    [StepArgumentTransformation(@"(defeat|am defeated by)")]
    public bool WinLoseToBool(string value)
    {
        return value == "defeat";
    }
    [Then(@"I (.*) the Joker")]
    public void SuccessCondition(bool value)
    {
        Assert.AreEqual(iAmBatman, value);
    }
}

关键因素是Given子句中的regex匹配由step参数转换匹配。因此,在I (.*) the Batman中,如果捕获匹配StepArgumentTransformation参数中的正则表达式,就像它在AmToBool的属性中所做的那样,那么这就是使用的转换。

根据您的问题和对Jakub回答的评论,看起来您正在尝试编写一个可以覆盖多个用户通过您的站点的旅程的单个步骤。SpecFlow并不是真的为这个设计的,它可能是一个指示,你应该尝试和改进你的场景/功能的结构。

直接回答你的问题,我不相信在你的步骤定义中有一种方法可以根据某些字符串的存在来推断布尔值。

如果你想坚持这条路线,那么你的原始示例可能是你最好的选择。

但是,我建议您不要采用这种方法,而是考虑重构您的步骤定义,以便将它们链接在一起,并跨场景重用它们。实际上,我正在努力思考一个适合您的解决方案的示例步骤定义。

一个多步骤方法的例子可能如下所示:

Given I have logged in as an existing user //1
And I have started my 6-step registration process //2
And I have filled in valid address values on step 1 //3
And I have left the fields blank on step 2 //4
... etc
When I save my registration

你的步骤将是:

  1. 导航到登录页面,以有效用户身份登录
  2. 导航到步骤1
  3. 用有效的输入填写字段,点击"下一步"
  4. 单击"next"

您只需要确保每个步骤尽可能地独立于其他步骤,这样您就可以用稍微不同的步骤替换一个步骤(对于新场景),而不会影响其他步骤。

使用这种方法,您仍然可以得到复杂(并且可能相当冗长)的场景,但我认为这是一个更好的解决方案,而不是试图聪明地将尽可能多的内容打包到单个步骤定义中。您可能会以无法阅读的场景结束,并且代码也可能难以阅读/维护。

您在找:

[Given(@"I do something (times) times")]
public void GivenIDoSomething(int times)
{
}

否则这似乎就足够了

[Given(@"I do something twice")]
public void GivenIDoSomethingTwice()
{
}

编辑

我认为,而不是if语句在步骤中,你实际上想要分开的步骤。