cucumber java从入门到精通(1)初体验
cucumber java从入门到精通(1)初体验
cucumber在ruby环境下表现让人惊叹,作为BDD框架的先驱,cucumber后来被移植到了多平台,有cucumber-js以及我们今天要介绍的主角cucumber-jvm。
先来看一下cucumber,简单来说cucumber是一个测试框架,就像是juint或是rspec一样,不过cucumber遵循的是BDD的原则。
BDD就是行为驱动开发,是一种软件开发流程或者说是软件开发实践,具体学术化的东西这里就不介绍了,归根到底,cucumber具有让你用自然语言编写用例的能力。
使用自然语言编写用例有很多好处,最直观的好处就是你的客户在一定的情况下是能够看懂你的测试用例的。最为项目的最核心因素,客户决定了项目该做成什么样,具有什么功能,不需要实现哪些功能。客户是需求的源泉,如果我们的测试用例很够很好的跟需求结合起来,比如说我们用自然语言写的测试用例如果能让用户认同,那么在这种情况下,测试用例基本等同于原始的需求文档了。需求文档是开发的凭据,这样一来根据测试用例来实现具体的需求就一定是客户所希望完成的需求了,毕竟这些需求是经过用户首肯的。这样一来,我们就等同于是让测试用例驱动了开发,这就是所谓的测试驱动开发的一种不太严谨的初体验了。
cucumber就是这样一种可以把需求转换为测试用例,让测试用例即需求的测试框架。概念东西不必太多先把cucumber java跑起来再说。
万事开头难,我们以最不自然的方式开始,先苦后甜。
下载jar包
首先下载cucumber-java的相关jar包,我整理了一下,放到了这里。
创建骨架
在这里要用到命令行,我们以windows平台为例。
# 创建名为cucumber_first的文件夹
mkdir cucumber_first
cd cucumber_first
# 创建jars文件夹,把下载下来的jar包全扔进来
mkdir jars
copy where\is\your\jars\*.jars jars
# 创建features文件夹
mkdir features
# 创建step_definitions文件夹
mkdir step_definitions
# 创建implementation文件夹
mkdir implementation
稍微解释一下这几个文件夹的作用
- features:用来存放自然语言的用例文件
- step_definitions:用来存放java代码实现的测试用例
- jars:cucumber-jvm的相关jar包都放在这里
- implementation:存放被测试的代码,也就是项目的实现文件
让项目跑起来
依然在命令行里,敲下面的命令
java -cp "./jars/*" cucumber.api.cli.Main features
你会看到下面的提示
No features found at [features]
0 Scenarios
0 Steps
0m0.000s
这行命令的意思就是运行features文件夹下面所有的自然语言测试用例。显然,我们没有任何测试用例,因此cucumber提示我们No features found at [features]。
创建feature文件
继续在命令行里奋战,我们创建1个空featrue文件
type nul > type nul > features\todo.feature
上面的命令的作用是在features文件夹下面创建名为todo.feature的文件,如果你使用的是linux系统,相应的命令就是touch features\todo.feature
我们的项目
我们的测试项目是实现1个超级简单的任务管理工具,简单来说就是实现1个todo list,我们可以往list里面添加任务,如果任务完成则将其置为已完成,仅此而已,小而丑。
定义第1个feature
简单来说,feature文件的内容就是我们使用自然语言编写的测试用例,是我们跟用户进行交流的文档。feature文件不是乱写的,它是有一些套路,是有规范的。简单来说,一个feature文件必须包含下面的一些内容
- Feature:用来描述我们需要测试的功能
- Scenario: 用来描述测试场景
- Given: 前置条件
- When: 描述测试步骤
- Then: 断言
下面我们要为我们的任务管理工具写1个测试用例,具体内容如下
Feature: 任务管理
Scenaro: 测试完成任务
Given: 我有3个任务
Then: 我完成了1个任务
Then: 我们还剩2个任务
中英结合,是不是看起来有点怪怪的?确实如此!
重构feature文件
cucumber支持使用40多种语言来描述feature文件,这就意味着我们可以使用中文来写feature。
下面我们用中文来重构一下
#language: zh-CN
功能:任务管理
场景: 完成1件任务
假设 我的任务清单里有3个任务
当 我完成1件任务之后
那么 我还剩下2件未完成的任务
可以看到Feature关键字在中文里可以用场景来替代,这样看起来就舒服多了。不过注意一下,上面的:
是英文的冒号,最好不要写成中文的冒号。
feature文件中英文关键字对照表
试着在命令行中使用下面的命令:
java -cp "./jars/*" cucumber.api.cli.Main --i18n zh-CN
该命令的输出结果就是feature文件中英文关键字的对照表。
| feature | "功能" |
| background | "背景" |
| scenario | "场景", "剧本" |
| scenario_outline | "场景大纲", "剧本大纲" |
| examples | "例子" |
| given | "* ", "假如", "假设", "假定" |
| when | "* ", "当" |
| then | "* ", "那么" |
| and | "* ", "而且", "并且", "同时" |
| but | "* ", "但是" |
| given (code) | "假如", "假设", "假定" |
| when (code) | "当" |
| then (code) | "那么" |
| and (code) | "而且", "并且", "同时" |
| but (code) | "但是" |
可以看到有些关键字对应了多种中文表达,不用困惑,这没关系,哪种表达方式用起来自然就用哪种。
运行feature
是时候运行一下我们刚写的feature了。
命令行里运行
java -cp "./jars/*" cucumber.api.cli.Main features
这个命令告诉cucumber,运行所有在features文件夹下的feature文件。
该命令会输出下面的结果
1 Scenarios (1 undefined)
3 Steps (3 undefined)
0m0.000s
You can implement missing steps with the snippets below:
@假设("^我的任务清单里有(\\d+)个任务$")
public void 我的任务清单里有_个任务(int arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@当("^我完成(\\d+)件任务之后$")
public void 我完成_件任务之后(int arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@那么("^我还剩下(\\d+)件未完成的任务$")
public void 我还剩下_件未完成的任务(int arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
逐行解释一下:
- 1 Scenarios (1 undefined): 我们在feature文件中描述了1个Scenario,但是我们只是描述,没有实现,这就是所谓的光说不练;
- 3 Steps (3 undefined): 我们描述了3个测试步骤,但我们仅仅是描述而已,没有实现这些步骤;
- 剩下的代码片段:告诉我们不要光说不练,要用下面的这些代码去实现这些场景和步骤;
如果运行时出现乱码,也就是说cucumber无法解析feature文件的话,记得将feature文件的编码改为utf8无bom
总结
可以看出,feature文件其实即使测试用例又是需求文档,当然了一个系统光有描述性质的测试用例和需求文档是远远不够的,下一节我们将会看到cucumber是怎样把单元测试用例和自然语言用例无缝关联的。
相关资料
cucumber java从入门到精通(1)初体验的更多相关文章
- cucumber java从入门到精通(4)Scenario Outline及数据驱动
cucumber java从入门到精通(4)Scenario Outline及数据驱动 到目前为止,我们的TodoList类工作良好,不过离我们的预期--任务清单系统还是有不少差距,究其原因不过如下: ...
- cucumber java从入门到精通(3)简单实现及断言
cucumber java从入门到精通(3)简单实现及断言 上一节里我们定义了step的java代码实现文件,step就是测试步骤及断言的集合,我们先定义出来,以后可以驱动开发以及在持续集成时重用. ...
- cucumber java从入门到精通(2)用代码定义步骤
cucumber java从入门到精通(2)用代码定义步骤 上一节里我们定义了feature文件,feature文件就是自然语言描述的用例文件,它有一定的章法,具体的潜规则是: 使用Feature关键 ...
- 《JAVA 从入门到精通》 - 正式走向JAVA项目开发的路
以前很多时候会开玩笑,说什么,三天学会PHP,七天精通Nodejs,xx天学会xx ... 一般来说,这样子说的多半都带有一点讽刺的意味,我也基本上从不相信什么快速入门.我以前在学校的时候自觉过很多门 ...
- 《Java从入门到精通》src0-8
public class HelloWorld { public static void main(String[] args) { System.out.println("Hello wo ...
- 《java从入门到精通》学习记录
目录 <Java从入门到精通>学习记录 3 基础的基础部分: 3 一. 常量与变量 3 1. 掌握: 3 (1) .常量与变量的声明方式: 3 (2) .变量的命名规则: 3 (3) .变 ...
- Java从入门到精通一步到位!
Java作为近几年来非常火的编程语言,转行来做Java的人不计其数,但如今真正的人才仍然匮乏,所以学习Java一定要有一个系统的学习规划课程.阿里云大学帮您规划Java学习路线可以帮助您从一个小白成长 ...
- Java从入门到精通——基础篇之JSTL标签
一.语言基础 EL(Expression Language)表达式,目的:为了使JSP写起来更加简单.提供了在 JSP 中简化表达式的方法. 二.分类 核心标签库:提供条件判断.属性访问.URL处理及 ...
- Java从入门到精通——基础篇之Servlet与JSP的区别
一.基本概念 1.1 Servlet Servlet是一种服务器端的Java应用程序,具有独立于平台和协议的特性,可以生成动态的Web页面.它担当客户请求(Web浏览器或其他HTTP客户程序)与服务器 ...
随机推荐
- java class 文件
class 文件是什么 1).是对一个java类或一个java接口的全面描述:2).是对java程序二进制文件格式的精确定义:3).一个class文件中只能包含一个类或接口:4).作为程序传给jvm的 ...
- WinForm 之 应用程序开机自启动设置方法
一.原理 需要开机自启动的程序,需要将其启动程序的路径写到注册表中指定的文件夹下. 二.实现方式 方法1:在生成安装程序时配置: 方法2:在程序运行时动态配置. 三.在生成安装程序时配置 1.右击安装 ...
- 微信小程序 - 组件传值给调用页面
演示如下(可以ctrl+鼠标放大或者下载GIF图片) 1. 先组件定义事件“checkbox”(组件内事件) 2. 调用页面调用它需要加bind:事件名 = 调用页面事件名(bind即绑定调用组件“o ...
- hadoop lzo应用
几种压缩方式对比: LZO example: https://github.com/twitter/hadoop-lzo/blob/master/src/test/java/com/hadoop/ma ...
- logback debug 日志没有信息
可能是项目绑定的日志不是logback的jar包,而是其他包,具体可查看tomcat启动日志 log4j:WARN No appenders could be found for logger (or ...
- ReactNative踩坑日志——fetch如何向服务器传递参数
一:简单参数 简单的参数,我们可以使用手动拼接的方式传递. 格式为: fetch(url?key1=val1&key2=val2&...).then((response) => ...
- ReactNative调用aar文件(附:如何打开、查看aar文件内容)
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7275897.html ReactNative可以用来进行一些嵌入式设备的操作终端开发,比如:ATM机.自动售卖 ...
- Android内存分析命令(转)
一.概述 1.1 内存指标概念 Item 全称 含义 等价 USS Unique Set Size 物理内存 进程独占的内存 PSS Proportional Set Size 物理内存 PSS= U ...
- Java DES 加解密("DES/EBC/NoPadding")
private static final Cipher DES_CIPHER; static { try { DES_CIPHER = Cipher.getInstance("DES/ECB ...
- V-rep学习笔记:Geometric Constraint Solver(几何约束求解)
The geometric constraint solver is slower and less precise at solving kinematic problems, but might ...