cucumber java从入门到精通(2)用代码定义步骤

上一节里我们定义了feature文件,feature文件就是自然语言描述的用例文件,它有一定的章法,具体的潜规则是:

  • 使用Feature关键字定义定义功能名称
  • 使用Scenaio关键字定义定义测试场景名称
  • 使用Given关键字定义定义前置条件
  • 使用When关键字定义定义测试步骤
  • 使用Then关键字定义定义断言

Feature文件是测试人员与客户/产品经理进行需求交流的文档工具,定义好Feature文件以后,我们的测试功能点实际上已经是定义完成了,下面的步骤很自然就是用代码去实现这些测试点。当然这里要说明的是,我们用人肉手点这些测试功能点也是没有太大问题的,但是想一想我们所处的开发阶段,现阶段我们只有整理成feature的原始需求,我们的系统还是一穷二白,一行代码都没有,因此用手点这个万能利器我们是无法使用的了。 再来思考一下如果我们使用代码去定义测试用例有什么好处?尽管系统目前没有任何功能,但这并不能妨碍我们把自动化的测试用例给写好(很大程度上,这是自动化的单元测试用例),有了用例,我们就有了标准。在后面的流程中只要开发人员编写的代码能够跑通这些自动化用例,那么我们可以比较有信心的认为开发实现了客户/产品经理所提出的需求。另外一点就是,自动化测试用例写完是可以重复使用的,在日后的回归测试、验收测试和持续集成的过程中,这些用例将起到保障产品/代码质量的关键作用。

使用cucumber定义用例(Step)

回到命令行,我们在cucumber_first\step_definitions文件夹下新建1个名为TodoStep.java的文件

 type nul > step_definitions\TodoStep.java

文本编辑器编辑该文件。在教程的开始阶段我们并不需要使用Java IDE,因此你不需要纠结到底是使用eclipse还是intellij。在windows系统上,比较推荐的文本编辑器有Notepad++, sublime, gvim。当然人各有所其所好,选择任意一种都是可以的,不过因为sublime和gvim在设置文件编码上面没有Notepad++直观,因此对于初学者来说使用Notepad++是一种比较稳妥的解决方案。

先把上一节中cucumber提示我们的那一大串代码片段复制进TodoStep.java,然后加入包名和依赖包的导入,你的TodoStep.java文件应该是这样的:

package step_definitions;

import cucumber.api.java.zh_cn.*;
import cucumber.api.PendingException;
import static org.junit.Assert.*; public class TodoStep {
@假设("^我的任务清单里有(\\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();
}
}

看上去哪里有点奇怪。的确如此,我们的方法名是中文的,这不太符合一般的代码审美。

重构方法名及参数名

是时候重构一下方法名和参数名了。这次我们重构的驱动力有下面2个:

  • 方法名是英文会让代码看上去更整洁;
  • 给方法的参数取一个更容易理解的名称会让代码在日后更容易维护。

重构完成以后,TodoStep.java中的代码应该是这样的:

package step_definitions;

import cucumber.api.java.zh_cn.*;
import cucumber.api.PendingException;
import static org.junit.Assert.*; public class TodoStep {
@假设("^我的任务清单里有(\\d+)个任务$")
public void iHaveSomeTasks(int totalTasks) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
} @当("^我完成(\\d+)件任务之后$")
public void iFinishSomeTasks(int finishedTasks) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
} @那么("^我还剩下(\\d+)件未完成的任务$")
public void iLeftSomeTasks(int leftTasks) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
}

重构完成之后我们发现我们的代码目的现在一目了然,增加了适当的可维护性。

注意:稳妥起见,请将TodoStep.java文件的编码改为gb2312。

运行steps

运行我们刚定义的steps需要2个步骤

  • 编译TodoStep.java文件
  • 运行feature文件的同时指定与feature文件相关的step文件所在的路径

看起来有点绕,其实在命令行中不难完成

首先执行编译命令:

# windows
javac -cp "./jars/*;." step_definitions\TodoStep.java # linux or unix
# javac -cp "./jars/*:." step_definitions\TodoStep.java

注意到我们把当前路径.加到了CLASSPATH里,这个很容易漏掉。

然后运行feature文件

java -cp "./jars/*;." cucumber.api.cli.Main -g step_definitions features

-g选项告诉cucumber我们要执行的steps文件存放在哪个文件夹里。同样需要注意的是当前路径.必须放到CLASSPATH里。

如果没有错误的话,你会看到下面的信息

    java -cp "./jars/*;." cucumber.api.cli.Main -g step_definitions features
P-- 1 Scenarios (1 pending)
3 Steps (2 skipped, 1 pending)
0m0.134s cucumber.api.PendingException: TODO: implement me
at step_definitions.TodoStep.iHaveSomeTasks(TodoStep.java:11)
at ?.假设我的任务清单里有3个任务(todo.feature:6)

这个提示信息告诉我们,我们定义了1个Scenario和3个Steps,不过我们并没有实现这些。因为我们的实现方法里只是简单的抛出了1个Pending异常。

Pending异常很像是占位符,它告诉代码的维护者这个测试步骤应该实现,只是现在还没开工而已。

自动化渐进

每次都在命令行里敲一长串命令除了会让你显得技术高超手法娴熟以外其实并不是什么特别有效率的事情(忽然想起来每次在命令行里用vim编辑文件各种前后台切换时总会有人发出惊叹)。而且命令越长出错的几率越大。

为什么不让这些命令自动执行呢?

先创建1个名为compile.bat的文件,我们用批处理的方式来自动运行命令。编辑之:

type nul > compile.bat
# compile.bat
javac -cp "./jars/*;." step_definitions\TodoStep.java

再创建1个名为run.bat的文件,输入如下内容

type nul > run.bat
# run.bat
java -cp "./jars/*;." cucumber.api.cli.Main -p pretty -g step_definitions features

现在我们可以把繁冗的命令简化成下面2个简单的指令了

compile
run

如果你是在linux或unix机器上,你可以这样做

touch compile
touch run echo 'javac -cp "./jars/*:." step_definitions\TodoStep.java' > compile
echo 'java -cp "./jars/*:." cucumber.api.cli.Main -p pretty -g step_definitions features ' > run chmod +x compile
chmod +x run ./compile
./run

总结

目前为止我们知道了2件事情

  • cucumber先定义feature文件,该文件是用自然语言描述的
  • 接下来要定义feature文件对应的step文件,这一步是用代码实现的

下一节我们将实现我们的第1个cucumber step及断言

cucumber java从入门到精通(2)用代码定义步骤的更多相关文章

  1. cucumber java从入门到精通(4)Scenario Outline及数据驱动

    cucumber java从入门到精通(4)Scenario Outline及数据驱动 到目前为止,我们的TodoList类工作良好,不过离我们的预期--任务清单系统还是有不少差距,究其原因不过如下: ...

  2. cucumber java从入门到精通(3)简单实现及断言

    cucumber java从入门到精通(3)简单实现及断言 上一节里我们定义了step的java代码实现文件,step就是测试步骤及断言的集合,我们先定义出来,以后可以驱动开发以及在持续集成时重用. ...

  3. cucumber java从入门到精通(1)初体验

    cucumber java从入门到精通(1)初体验 cucumber在ruby环境下表现让人惊叹,作为BDD框架的先驱,cucumber后来被移植到了多平台,有cucumber-js以及我们今天要介绍 ...

  4. 《JAVA 从入门到精通》 - 正式走向JAVA项目开发的路

    以前很多时候会开玩笑,说什么,三天学会PHP,七天精通Nodejs,xx天学会xx ... 一般来说,这样子说的多半都带有一点讽刺的意味,我也基本上从不相信什么快速入门.我以前在学校的时候自觉过很多门 ...

  5. 《Java从入门到精通》src0-8

    public class HelloWorld { public static void main(String[] args) { System.out.println("Hello wo ...

  6. 《java从入门到精通》学习记录

    目录 <Java从入门到精通>学习记录 3 基础的基础部分: 3 一. 常量与变量 3 1. 掌握: 3 (1) .常量与变量的声明方式: 3 (2) .变量的命名规则: 3 (3) .变 ...

  7. [数据结构-平衡树]普通 FHQ_Treap从入门到精通(注释比代码多系列)

    普通 FHQ_Treap从入门到精通(注释比代码多系列) 前提说明,作者写注释太累了,文章里的部分讲解来源于Oi-wiki,并根据代码,有部分增改.本文仅仅发布于博客园,其他地方出现本文,均是未经许可 ...

  8. Java从入门到精通一步到位!

    Java作为近几年来非常火的编程语言,转行来做Java的人不计其数,但如今真正的人才仍然匮乏,所以学习Java一定要有一个系统的学习规划课程.阿里云大学帮您规划Java学习路线可以帮助您从一个小白成长 ...

  9. Java从入门到精通——基础篇之JSTL标签

    一.语言基础 EL(Expression Language)表达式,目的:为了使JSP写起来更加简单.提供了在 JSP 中简化表达式的方法. 二.分类 核心标签库:提供条件判断.属性访问.URL处理及 ...

随机推荐

  1. 【树莓派】crontab设置Linux设备定时重启

    简介:设置Linux设备定时重启或者关机 问题:有台设备每天总需要使用的人手动重启一下才可以正常工作,但是检查了日志,看起来服务一切都正常.时间和正确时间相差4mins. 解决办法: 1.增加定时任务 ...

  2. 1052: 旋转单词(words)

    #include <iostream> #include <iomanip> #include <cstdlib> #include <string> ...

  3. CTP交易函数大全

    管理接口 交易接口

  4. 不同版本的tomcat下载路径

    1.由于安全问题,有些tomcat存在漏洞.为了升级要么修复漏洞,要么就直接升级tomcat. 一般升级tomcat比较省事.但是找到相应版本的tomcat比较难,所以还是要自己寻找对应的tomcat ...

  5. CentOS 6.9 下安装DB2

    操作系统:CentOS6.9_x64 DB2安装文件: db2_v101_linuxx64_expc.tar.gz 安装数据库 tar zxvf db2_v101_linuxx64_expc.tar. ...

  6. jmap 命令

    1.  jmap -heap pid          查看java 堆(heap)使用情况         using thread-local object allocation.         ...

  7. java 反汇编class文件

      Created by Marydon on 1.情景展示 如何使用Java命令将字节码文件(class文件)反汇编? 2.解决方案 反汇编:将java文件编译后的class文件反汇编进而看到jav ...

  8. 〖Linux〗穿越城墙之后,直接连接国内网站的路由配置

    因为有需要做Android相关的开发工作,很多时候要穿越之后才能做事情: 如Android文件加密预研.Android NDK/SDK的下载,都需要使用得到Google: 但是穿越之后,访问国内网站就 ...

  9. BackBone.js之Router

    一.前言 有一段时间没有写随笔了,可能是最近的烦心事有点多.不倾诉了,开始我们的主题吧,以前做过一个web的聊天平台,js的代码足足有2k行. 虽然是在一个星期就完成了,但是想想还是不服.一定有一种更 ...

  10. python 模块之os.path模块

    # -*- coding: cp936 -*- #python 27 #xiaodeng #python 模块之os.path模块 #http://www.cnblogs.com/dkblog/arc ...