Specflow Scenario Outline不生成预期的步骤代码

时间:2013-12-12 00:53:59

标签: c# bdd specflow gherkin

这是我的小黄瓜:

Scenario Outline: Login using valid email address
Given I have not logged into the current computer
And Username <username> and password <password> is a valid account
When I start the client
And Login using username <username> and password <password>
Then The client should navigate to first time screen

Examples: 
| username         | password    |
| valid001@xyz.com | password001 |
| valid002         | password002 |

这将生成以下步骤文件:

[Binding]
public class UserLoginSteps
{
    [Given(@"I have not logged into the current computer")]
    public void GivenIHaveNotLoggedIntoTheCurrentComputer()
    {
        ScenarioContext.Current.Pending();
    }

    [Given(@"Username valid(.*)@xyz\.com and password password(.*) is a valid account")]
    public void GivenUsernameValidXyz_ComAndPasswordPasswordIsAValidAccount(int p0, int p1)
    {
        ScenarioContext.Current.Pending();
    }

    [When(@"I start the client")]
    public void WhenIStartTheClient()
    {
        ScenarioContext.Current.Pending();
    }

    [When(@"Login using username valid(.*)@xyz\.com and password password(.*)")]
    public void WhenLoginUsingUsernameValidXyz_ComAndPasswordPassword(int p0, int p1)
    {
        ScenarioContext.Current.Pending();
    }

    [Then(@"The client should navigate to first time screen")]
    public void ThenTheClientShouldNavigateToFirstTimeScreen()
    {
        ScenarioContext.Current.Pending();
    }
}

问题如下:

  • 用户名的生成正则表达式基于示例列中的第一个条目。这不是我想要的,因为并非所有示例都遵循该模式。
  • 方法名称使用示例列中的第一个条目(即 WhenLoginUsingUsernameValidXyz_ComAndPasswordPassword )。这很难理解,如果示例表中的数据更改,则方法名称不再正确
  • 参数的类型为 int 。它们应该是字符串。

我希望步骤定义生成输出如下:

    [When(@"Login using username (.*) and password (.*)")]
    public void WhenLoginUsingUsernameAndPassword(string p0, string p1)
    {
        ScenarioContext.Current.Pending();
    }

我错过了什么吗?有没有办法影响SpecFlow为场景大纲生成步骤方法的方式?如果没有,那么解决这个问题的最佳方法是什么?如果没有让特征生成的代码破坏我的更改

2 个答案:

答案 0 :(得分:4)

总之,好消息。这些自动生成的绑定只是一种方便,不会自动重新生成。事实上,我自己总是手工制作这些。

这意味着你可以去改变它们而不用担心它们会被摧毁: - )

每次编辑* .feature文件时,SpecFlow都会自动生成* .feature.cs文件。这些永远不应该被编辑,但是如果你浏览它们,你可以看到它们基本上从你的场景中获取Given,When和Then行,并将它们作为参数传递给它自己的内部方法。在幕后,SpecFlow使用反射来查找所有具有[Binding]属性的类,然后查看所有具有[Given][When]或{{1}的类方法找到正则表达式列表的属性。最匹配的正则表达式标识要调用的方法。这就是为什么Bindings经常被描述为全局的,并且不应该真正使用继承来构建(因为你最终得到了多个相同的正则表达式)。

回到生成的绑定,只有在SpecFlow的VS插件检测到您没有匹配的正则表达式且尝试导航到功能文件中的定义(F12)时,才会在编辑器中创建这些绑定。它们确实是您构建的占位符。

答案 1 :(得分:0)

您应该使用单引号来表示SpecFlow必须使用整个字符串而不是数字。

filedata = fopen('fname1.txt','rt'); 
%fname1.txt is created by a C program. I am quite sure that the problem isn't there.
scanned = textscan(filedata,'%s','Delimiter','\n');
raw = scanned{1};
stringValues = strings(50,1);
for K=1:length(raw)
    stringValues(K)=raw{K};
end
clear K %purely for convenience

regex = 'x=(?<x>[\-\.0-9]*),f1=(?<f1>[\-\.0-9]*),f2=(?<f2>[\-\.0-9]*)';
tokens = regexp(stringValues,regex,'names');

x = zeros(50,1,'single');
f1 = zeros(50,1,'single');
f2 = zeros(50,1,'single');

for L=1:length(tokens)
    x(L)=tokens{L}.x;
    f1(L)=tokens{L}.f1;
    f2(L)=tokens{L}.f2;
end