我在项目中只用到其中部分的特性,接下来写一下我使用SpecFlow这个工具所用到的一些特性。可能很多地方还需要改善,欢迎用过得朋友提建议。
(SpecFlow的wiki上有它的Documentation全面的介绍,有兴趣的朋友也可以看看:https://github.com/techtalk/SpecFlow/wiki/Documentation)
Step Definitions:这是SpecFlow最基本的特性。Step Definitions通过绑定(Bindings)来把自然语言的规范(Specification)和应用程序接口链接起来。
正则表达式:在实际项目中我们会遇到很多类似的语句,比如下面2个步骤
When I click the 'Login' button"
When I click the 'Register' button"
…….
还有其他button的点击步骤,如果每个都单独实现脚本,可能如下:
[When("I click the 'Login' button")]
public void AndIClickTheLoginButton()
{
var loginButton = WebBrowser.Current.Button(Find.ByValue("Login"));
if(!loginButton.Exists)
Assert.Fail("Expected to find a button with the value of 'Login'.");
loginButton.Click();
}
[When("I click the 'Register' button")]
public void AndIClickTheRegisterButton()
{
var registerButton = WebBrowser.Current.Button(Find.ByValue("Register"));
if(!registerButton.Exists)
Assert.Fail("Expected to find a button with the value of 'Register'.");
registerButton.Click();
}
可以看出的是我们脚本存在大量的重复,测试也需要重构。幸运的是SpecFlow提供了参数话来避免这个问题。这里每个步骤都是WatiN通过找到某个button,然后点击它。我们就可以用正则表达式捕捉到button的一些属性,然后把这个属性作为参数传给step definition方法。例如:
[When("I click the '(.*)' button")]
public void AndIClickAButton(string buttonText)
{
var button = WebBrowser.Current.Button(Find.ByValue(buttonText));
if(!button.Exists)
Assert.Fail("Expected to find a button with the value of '{0}'.", buttonText);
button.Click();
}
多标记:有时很多Steps步骤的描述很类似却不完全相同,但是实现方法类似。我们可以在同一个方法上标记多个steps的描述性语句。例如:
[Given(@"I create a new general activity")]
[When(@"I create a new general activity")]
public void WhenICreateANewGeneralActivity()
{
//some test code here….
}
表格参数:在步骤中可以使用表格形式的参数,可以让scenario更直接明了,例如:
Scenario: Fill Machine With Coffee, Chocholate And Tea
Given I have filled machine with
|Drink |Count |
|Coffee |5 |
|Tea |2 |
|Chocholate |3 |
When I press the service button
Then I should get a message "There are 10 drinks in the machine"
绑定的测试方法如下:
[Given(@"I have filled machine with")]
public void GivenIHaveFilledMachineWith(Table table)
{
foreach (var row in table.Rows)
{
if (row[0] == "Coffee")
{
target.LoadCoffee(int.Parse(row[1]));
}
if (row[0] == "Tea")
{
target.LoadTea(int.Parse(row[1]));
}
if (row[0] == "Chocholate")
{
target.LoadChocholate(int.Parse(row[1]));
}
}
}
这是几种常见Step Definitions的做法,下篇继续介绍Binding相关的特性