Cucumber是程序员用于测试其他软件的开源软件工具 [1] 。它运行以行为驱动开发(BDD)风格编写的自动验收测试。BDD方法的核心是其简单的语言解析器,称为Gherkin [2] 。它允许用客户可以理解的逻辑语言来指定预期的软件行为。因此,Cucumber允许执行用面向业务的文本编写的功能文档。
Cucumber用Gherkin语法 [3] ,它是一种用自然语言来定义测试用例。它被设计成非技术人员都可以读懂的,并且共同描述与软件系统有关的用例。Gherkin的语法背后的目的是促进整个开发团队(包括业务分析师和经理)的行为驱动开发实践。它试图从企业管理的需求定义的初始阶段开始,并在开发生命周期的其他阶段执行稳固,明确的需求
Cucumber-JVM是cucumber在java平台上的使用,结合junit进行java项目测试。
一个简单基于maven项目管理的cucumber架构:
测试程序入口,通过@CucumberOptions(plugin={"pretty"}, features={"src/test/features"},glue = {"steps"}) 指定feature文件和step文件的存放位置。Plugin是指运行结果生成 html 文件和 json 文件。
测试用例的存放地方。例子中的内容为测试数据。
将feature中的自然语言转换为java自动化测试脚本
正式项目中开发人员编写的项目代码,测试人员在step自动化脚本中进行调用和测试。
Maven管理项目的文件,在dependencies中声明需要的jar资源。
New—project—maven—maven project
使用cucumber架构进行测试,遵循BDD(行为驱动开发-Behavior-Driven Development)原则。测试人员根据原始需求,使用自然语言编写feature(既是需要文档,也是测试方案与用例)。然后根据feature进一步编写step(自动化脚本)。 Feature编写完成之后,经过dry run可以快速生成step内容:
编写完成的feature文件:
通过AppTest.java右键run as—Junit Test,结果如下:
将以上内容填充到*step.java中,再进一步编写自动化脚本即可。
与传统测试用例文档的对照:
英文关键字 |
中文关键字 |
传统测试用例对照 |
feature |
功能 |
测试套名称 |
background |
背景 |
测试套预置条件 |
scenario |
场景, "剧本" |
测试用例 |
scenario_outline |
场景大纲, "剧本大纲" |
测试用例大纲 |
examples |
例子 |
测试数据 |
given |
* , "假如", "假设", "假定" |
测试用例预置条件 |
when |
* , "当" |
测试用例操作步骤 |
then |
* , "那么" |
测试用例预期结果 |
and |
* , "而且", "并且", "同时" |
"而且", "并且", "同时" |
but |
* , "但是" |
"但是" |
given (code) |
假如, "假设", "假定" |
假如, "假设", "假定" |
when (code) |
当 |
当 |
then (code) |
那么 |
那么 |
and (code) |
而且, "并且", "同时" |
而且, "并且", "同时" |
but (code) |
但是 |
但是 |
执行java -cp "jars/*" cucumber.api.cli.Main --i18n zh-CN可以看到上诉关键字对照。
features:执行feature文件的目录(按顺序读取目录下所有feature文件)或者直接指定某个或者多个feature文件(按照参数顺序)进行解析。
glue:为features指定step definitions路径。
tags:只执行带参数tag的用例代码。详细使用见后续章节。
Plugin:用来指定生成的报告格式,多种格式用逗号隔开。
在feature文件中加上tag:
在测试入口中@CucumberOptions调用中,通过tags关键字进行组织调用:
~符号表示非。通过tag之间的组合,可以实现用例选取。例如整个测试套中有一个10个用例,通过tag调用能只测试其中5个测试用例。
调试结果,可以看到tag1的测试用例没有执行:
string类型
Dry run之后,自动匹配生成参数为string类型的的函数:
int类型
dry run之后:
DataTable类型
Step中实现如下:
Datatable方法,详细使用方法和数据结构可以直接查看DataTable.class源码:
Backfround
如果有多个案例中存在重复的given and ,可以使用backfround进行替换:
通过background复用,可优化为:
Hook
By definition, hooks allow us to perform actions at various points in the cucumber test cycle.
未通过hook复用前,1.feature如下:
#NEW的步骤,和测试场景无必然联系,但是每次测试套执行前或者执行后都需要操作,所以可以通过hook复用。
在step文件中写好hook:
然后1.feature可以优化2.feature:
可以进一步使用tag hook进行优化(在hook前加上tag进行标记):
Background与Hook
Hook优点:hooks的优点是可以在每个scenario之前或之后做一些共同的操作。
Hook缺点:Hooks是在java文件中定义的,对于非技术人员来说是不易读的,除非case失败,否则不会有什么证据表明它们的存在。在这种情况下,我们就可以使用Background.
当我们希望steps在feature文件里面可见时,我们可以使用background代替Before钩子,它们可以为每个scenario创建逻辑的上下文。Background会在每个scenario之前执行,就像Before钩子一样。但如果存在Before 钩子,那个它们会先于background执行。当我们有相同的操作时,为了遵守DRY原则,我们可以选择hooks或background。至于选择哪一种方式,取决于当它们明确的出现在feature文件里是否有价值。
网上参考资料:
http://www.cnblogs.com/nbkhic/category/743780.html
https://www.ibm.com/developerworks/cn/java/j-lo-cucumber01/
https://blog.csdn.net/liuchuanhong1/article/details/52210477(cucumber字符转换)
https://www.coveros.com/background-and-hooks-for-cucumber-jvm/ (cucumber复用)
https://github.com/cucumber/cucumber/tree/master/datatable (datatable使用)
https://zsoltfabok.com/blog/2012/09/cucumber-jvm-hooks/ (hook的使用)