2013-04-24 81 views
7

在SpecFlow,我想检查一个字符串的一个步骤定义,并在那一刻我做笨重的事情就是这样人为的例子存在:布尔参数步骤

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

不过,我D喜欢做这样的事情:

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

但我不能找出如何,这是可能的,如果是这样怎么样?

+0

在这种情况下,布尔标志的含义是什么?当两次==假时,做两次事情意味着什么? – 2013-04-24 14:54:53

+0

这是一个制作的例子,所以可能不是最好的。我只想要一个很好的方法来查找特征文件中的步骤中是否存在字符串。 – 2013-04-24 14:57:06

+1

很高兴看到真实的例子......对我而言,您的问题可能与您编写场景的方式有关。 – 2013-04-24 14:59:12

回答

0

你是否在寻找:

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

否则这似乎足以

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

编辑

我认为,在步骤而不是if声明你真的想独立的步骤。

+0

忽略两位;我已经编辑了这个问题,说明这个例子是完全构成的,而不是实际的代码。 – 2013-04-24 14:59:44

+0

本来我是这么做的,但是导致了难以提取的细微差异。在不扰乱客户的情况下,我不能发布我们拥有的例子。 – 2013-04-24 15:05:30

+0

你的步骤应该以'可重用'的方式实现,所以你应该能够在场景中使用'GivenFoo'步骤两次:'给定IDoFoo和IDoFoo当xxxx然后yyyy'。 SpecFlow中没有任何内容检查字符串的存在并将其转换为布尔值。你的'if(bar ==“bar”)'是我能想到的唯一方法,而不用重构你的步骤。 – 2013-04-24 15:08:45

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. 单击'下一个'

您只需要确保每一步都尽可能独立于其他步骤,以便在不影响其他步骤的情况下将一个步骤替换为一个细微差别的步骤(对于新的场景)。

通过这种方法,你仍然可以使用复杂的(和潜在的非常详细)的场景结束,但我认为这是不是巧言令色和包装尽可能多的到一个单一的步骤定义一个更好的解决方案。你最终可能会遇到无法阅读的场景,并且代码也可能会很难读取/维护。

+0

>“...试图编写一个单一的步骤,可以覆盖通过您的网站的多个用户旅程SpecFlow并非真正为此设计” 看来SpecFlow的设计正是为了这一点,因为他们使他们的步骤全球化,甚至说“小心!将步骤定义与特征耦合是一种反模式”。他们甚至连接到黄瓜文档,说不重用步骤是“邪恶的,因为它可能导致步骤定义的爆炸,代码重复和高维护成本。” – LouD 2016-02-19 14:44:20

0

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