摘要
本文从实际使用Cucumber这一工具的角度,以Cucumber-JVM实现为基础,采用了不同的事例阐述了:如何编写feature文件,如何从feature文件生成对应的Steps,如何生成不同格式的报告,如何定制化的运行测试用例以及在与其他主流工具结合中如何避免报告失真、如何与主流持续集成工具结合使用等,为大家在日常工作中使用Cucumber释疑解惑。
Cucumber是什么
Cucumber是BDD模式下实现可执行规范(Executable Specifications)的开源工具,但是它的使命并不局限于做自动化验收测试,更加重要的在于其能够在团队成员之间构建统一的交流基础(feature文件)、规范交流用语(Domain Specific Language)、提高各个利益相关方(Business Stakeholders)沟通效率和效果从而达到提升产品质量、做成客户期望得到的产品这一最终目标。
如何使用Cucumber
Cucumber有很多种语言的实现版本,例如Java、Ruby、.NET、JavaScript等等,并且Cucumber可以和主流的测试框架很好地集成,常见的Selenium、SpringFramework、Ruby on Rails等,能够方便地引入到你的测试工作中去,几乎没有任何门槛。以一个Java测试项目为例,介绍如何使用Cucumber的Java语言实现版本:Cucumber-JVM。
将Cucumber-JVM依赖加入到项目中
如果你的项目是使用Maven管理所依赖的第三方依赖jar包,那么引入Cucumber-JVM将是一件优雅而且轻松的事情,只需要简单的将如下的Code Snippet加入到项目的pom.xml的“dependencies”下即可:
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-java</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-junit</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
关于version,请尽量选择适合自己项目的,如果你使用的是Java 7,如果没有特殊的要求可以与本文一样采用<cucumber.version>1.2.2</cucumber.version>
编写 Executable Specification
Cucumber之所以受到如此的推崇,与其Executable Specification这个特性不无关系。顾名思义,可执行规范给出了至少两个方面的意义:
- 可执行性(Executable):你可以像执行代码(Java、Ruby…)一样运行这些规范,来验证、验收目标应用。当然,这一点是从技术人员的视角来看的;
- 规范性(Specification):从非技术人员的视角触发,相比验证本身,他们更加关心系统功能的清晰描述:系统在什么场景下能够做什么样的事情。
这看似简单的两方面似乎关联并不是很大,但是如何能够在同一个基础(feature files)之上做到两者的融合,却是Cucumber最大的妙处。从项目管理人员的角度来看,Cucumber是技术人员和非技术人员交流的桥梁,从更加深的层面来看,Cucumber能够使增加各个利益相关方的沟通,因为只有深入的沟通,在各方都理解了真正期望的功能这一基础之上,才能产出都认可的Executable Specification!
回归到工具这一层面,Cucumber是以feature文件来组织测试的,相信大家都很清楚这里之所以采用feature这个后缀,其实正是为了凸显用户在使用系统中所能够享受到的服务和功能。以ATM取钱场景为例子,通过如下的大致步骤:
- 创建feature文件,
- 生成测试Step Definitions,
- 运行测试用例。
来具体说明如何在测试工作中使用Cucumber。
创建Feature文件
自动柜员机(ATM)大家都非常熟悉,现在假设你在为某一个银行所提供的固定金额取款功能编写测试用例,经过跟利益相关方讨论之后,针对这一功能,你们得出了如下的场景定义,此处以Feature文件的形式写出来:
src/main/resources/features/FixedAmountWithdraw.feature
# language: zh-CN
功能: 使用ATM固定金额方式取款
通常“取款”菜单包含了几个固定金额,使用这些固定金额取款可以避免从键盘输入提取金额,从而可以加速交易,提高取款的效率。
场景大纲: 固定金额取款
假如 我的账户中有余额"<accountBalance>"元
当 我选择固定金额取款方式取出"<withdrawAmount>"元
那么 我应该收到现金"<receivedAmount>"元
而且 我账户的余额应该是"<remainingBalance>"元
例子:
| accountBalance | withdrawAmount | receivedAmount | remainingBalance |</