8

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

但我不知道怎么做,这可能吗?如果可以,怎么办?

4

3 回答 3

5

你绝对可以做那种事情,使用一种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 绑定 (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子句中的正则表达式匹配由 step 参数转换匹配。因此I (.*) the Batman,如果捕获匹配 StepArgumentTransformation 的参数中的正则表达式,就像它在属性中所做的那样,AmToBool那么这就是使用的转换。

于 2018-02-02T23:35:01.550 回答
1

根据您的问题和对 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. 点击下一步'

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

使用这种方法,您仍然可能会遇到复杂(并且可能非常冗长)的场景,但我认为这比试图变得聪明并将尽可能多的内容打包到单个步骤定义中是更好的解决方案。您可能最终会遇到不可读的场景,并且代码可能也很难阅读/维护。

于 2013-05-01T06:07:54.757 回答
0

您是否在寻找:

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

否则这似乎就足够了

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

编辑

我认为if您实际上想要分离步骤,而不是在步骤中声明。

于 2013-04-24T14:56:44.250 回答