杨晔
(浙江警官职业学院信息技术与管理系,浙江 杭州 310018)
基于BDD的自动化测试框架研究
杨晔
(浙江警官职业学院信息技术与管理系,浙江杭州310018)
敏捷开发模式的盛行掀起了自动化测试的一轮热潮,测试和开发合作越来越密切。本文研究的自动化测试框架,将BDD的敏捷开发理念与软件测试相融合,通过统一的Gherkin语言定义验收测试标准,帮助业务人员、测试人员和开发人员形成对需求明确统一的认识,然后通过web driver测试代码实现可执行的验收测试,以TDD的方式实现产品代码。该框架使用Specflow、Selenium和MsTest等测试工具,真正实现了自动化测试,大大减少了手工测试的压力,促进开发测试过程中软件开发涉众之间的沟通,及时得到用户反馈,满足快速发布产品的需求,提升产品质量。
自动化测试;BDD;Specflow;Selenium;Scenario
随着信息化步伐不断加快,软件作为处理业务和提供服务的重要保障,其开发任务日趋繁重,各类管理软件也变得越来越庞大和复杂,这就对软件测试提出了更高的要求。为了节省大量的时间和开支,必须使用自动化测试技术代替效率低下的手工测试,节省软件测试成本,缩短产品发布周期。
虽然现在有很多录制/回放的测试工具可用于自动化测试,但是由于捕捉方式产生脚本的数据硬编码问题,测试人员需要不断地修改脚本以适应应用程序的变化,导致测试效率并没有得到有效提高。因此本文结合敏捷测试流程和自动化实施方法,给出基于BDD的自动化测试框架设计和应用分析。
软件开发过程中最常见的两个问题是需求和开发脱节、开发和测试脱节。用户想要的功能没有开发,开发的功能并非用户想要,用户和开发人员所说语言不同。开发和测试被认为是割裂的,从开发到测试周期过程,测试自动化程度低。使用BDD(Behavior Driven Development,行为驱动开发)技术可以解决需求和开发脱节的问题,从用户的需求出发,保证程序实现效果与用户需求一致。BDD的出现解决了测试驱动开发中常遇到的问题,比如从哪里开始测试,应该测试什么,不应该测试什么等。
BDD在继承TDD(Test Driven Development,测试驱动开发)的基础上,通过为验收测试创建测试,实现关注点分离,优化过程管理。BDD开发关注用户情景以及围绕这些情景建立逻辑和测试,通过领域特定语言(Domain Specific Language,DSL)来描述系统行为,再以这些行为为驱动,编写产品代码来实现这些行为。通过Domain的表达方式,来描述系统的Feature与用户的Scenario,并依据这些Scenario来产生对应的code flow template,接着可结合单元测试的3A原则,即Arrange-Act-Assert,来验证系统功能是否有满足这些Scenario。
自动化测试框架融合框架开发思想,结合测试流程和工具,能够实现自动化测试的规模化,提高测试效率,保证测试质量。自动化测试框架的好坏直接影响到自动化测试的成功与否。一个完整的自动化框架能够为测试人员提供测试用例的设计、开发、执行、结果分析的界面,为测试过程提供数据保存的场所,为测试执行提供驱动。在此基础上,才能为测试实现自动化提供技术可能,加上团队、流程、管理的配合,最终形成一个完整的软件测试自动化解决方案。本文提出的基于BDD的自动化测试框架图如图1所示。
图1 基于BDD的自动化测试框架图
该框架融合BDD的开发流程和分层测试的理念,能够适应敏捷开发的测试流程,将测试活动前置,实现了需求的实例化和可执行,真正实现了自动化验收测试带来的收益,从而让团队真正享受到自动化测试带来的收益。同时该框架使及时全面的回归测试、稳定性测试、兼容性测试成为可能,为持续集成提供基础,便于重现或校验偶发性缺陷。
在框架中,首先获取客户的商业目标,找到特征功能,编写用户故事,定义与管理用户需求。然后编写验收测试用例,定义用户故事的完成事项,使用BDD规范的Feature和Scenario,描述验收测试用例所对应的系统行为,这样在验证软件的同时,自动升级了技术和功能文档,更容易开发出高质量的代码,易于使用、维护和测试。使用UI测试和Service测试技术编写相应的Step Template,生成自动化的验收测试用例,这样就形成了可执行的需求规范。然后进入TDD的循环过程,以测试驱动完成生产代码的编写,同时完成Unit测试。
进行BDD实践首先要解决两个问题,一是如何实现一个能够描述系统行为(业务价值)、非技术人员可读的测试,二是如何让这个测试变得可执行。目前有很多工具可在开发过程中实现BDD,包括Jbehave、Cucumber、Lettuce、Rspec和SpecFlow等。这些BDD框架各自提供了一套DSL,开发人员可以使用DSL描述业务需求。同时,这些框架都依赖于Web Driver,BDD框架通过Web Driver调用浏览器的接口,模拟用户输入,读取浏览器页面上显示的内容用于验证。
在本文中的BDD工具,我们将采用ASP.NET MVC框架进行开发,IDE使用Microsoft Visual Studio。在测试框架中,我们将采用SpecFlow和WebDriver工具Selenium实现自动化验收测试,Service测试和Unit测试将采用MSTest。
已知某单位的设备管理系统,可以实现对设备的信息管理、报修处理等功能。现将使用基于BDD的自动化测试框架,实现并测试登录模块。
(1)用SpecFlow描述业务价值
在自动化验收测试层,我们首先安装配置好BDD测试框架工具SpecFlow,然后根据用户需求故事和验收条件,编写Features和Scenarioes脚本。当前登录功能可以划分为以下几个场景:
1)用户名密码匹配,登录成功;
2)用户名或密码不匹配,登录失败,并给出相应提示。
BDD使用Gherkin语言来定义系统行为。Gherkin是一种领域特定语言,它允许我们在不解释具体执行细节的情况下,详细描述应用应该如何执行。需求的大部分内容是由自由文字组成,只有几个特定的Gherkin关键字:Feature、Scenario、Given、When、And和Then,其他的都是自由文字,并且主要记录了功能特性是如何被使用的。Gherkin是一种基于行的编程语言,场景中的每一行(Line)就是一个步骤(Step)。
以用SpecFlow的DSL描述登录成功任务作说明,其他情况相同,得到测试场景代码如下:
Feature:User Login
In order to access my account As a user of the website
I want to log into the website
Background:There is a user with the following login detail:
|LoginName|Password|
|my@example.com|test|
Scenario:Login succeed
Given the user is at the login page
When the user fill in the account information:
|LoginName|Password|
|my@example.com|test|
And the user click the login button
Then the user should be at the
|http://localhost:57499/Consumer/Index|
And the page should display the
|pageContent|
|我的设备管理系统|
这些代码计划就是遵循了一定格式的英语,即使看不懂代码的产品经理、业务分析师也能够通过此文档和开发人员顺畅地交流。用Specflow把一个需求的不同场景描述出来,也是从不同角度阐述了这个需求的业务价值。Specflow的目标就是书写可执行的,能够表述业务价值的文档。
(2)Web Driver与页面交互
接下来需要让文档执行起来,Specflow提供了把业务逻辑转换为可执行代码的机制Step Definition。然后我们使用Web Driver,像真实用户那样打开浏览器,输入用户名密码,点击提交按钮,验证登录是否成功。这里我们选用了比较流行的Web Driver框架Selenium 2,具体Step Definition实现代码如下:
[Binding]
public class UserLoginSteps
{
private IWebDriver driver;
[Given(@"the user is at the login page")]
public void GivenTheUserIsAtTheLoginPage()
{
driver=new FirefoxDriver();
driver.Navigate().GoToUrl("http://localhost:57499/Account/Login");
}
[When(@"the user fill in the account information:")]
public void WhenTheUserFillInTheAccountInformation (Table table)
{
driver.FindElement(By.Id("LoginName")).SendKeys(table.Rows[0][0]);
driver.FindElement(By.Id("Password")).SendKeys(table. Rows[0][1]);
}
[When(@"the user click the login button")]
public void WhenTheUserClickTheLoginButton()
{
driver.FindElement(By.Id("loginSubmit")).Click();
}
[Then(@"the user should be at the(.*)page:")]
public void ThenTheUserShouldBeAtThePage(string p0, Table table)
{
var expectedURL=table.Rows[0][0];
var actualURL=driver.Url;
Assert.AreEqual(expectedURL,actualURL,"没有跳转到{0}的页面。",p0);
} [Then(@"the page should display the(.*)information:")] publicvoid ThenThePageShouldBeDisplayedCorrectly (string p0,Table table)
{
string expectedWords=table.Rows[0][0];
string actualWords=driver.FindElement(By.XPath("html/body/div[1]/div/h1")).Text;
bool isContained=actualWords.Contains(expected-Words);
Assert.IsTrue(isContained,"页面中没有找到要检查的词语{0}",p0);
driver.Close();
driver.Quit();
driver=null;
}
这段代码将打开浏览器,访问地址 http://localhost: 51426/Account/Login/,在邮件输入框输入“my@example. com”,在密码输入框输入“test”,点击“登录”按钮,验证测试结果是否正确跳转到“http://localhost:51426/Consumer/Index”,并且打开的页面包含登录成功后的“学生后台管理首页”字样,如果成功,则测试通过,否则失败。
Web Driver通过调用浏览器的支持自动化的API,模拟真实用户在浏览器上的操作。把这段代码放在上面的Step Definition中,当Specflow测试运行的时候,这段代码就会运行,完成登录操作。
(3)运行自动化验收测试
通过Specflow对需求进行编码,并使用Selenium将其转换成验收测试,这样真正实现了和代码相关的验收测试,并且可以不依赖具体实现,而是从UI层上进行确认。运行验收测试的方法可以使用Visual Studio的测试资源管理器,同时使用MSTest。此处以MSTest为例,结果如下:
*****KnowledgeDot.Test.Specs.Features.LoginFeature.Login-SucceedAsStudent_Given I am at the login page
->done:LoginSteps.GivenIAmAtTheLoginPage()(8.3s)
When I fill in the account information:
---table step argument---
|UserName|Password|Role|
|stu|stu|学生|
->done:LoginSteps.WhenIFillInTheFollowingForm(