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

到目前为止,我们的TodoList类工作良好,不过离我们的预期——任务清单系统还是有不少差距,究其原因不过如下:

我们的feature不太完毕,没有测试任务清单的增删改查完成等功能;

我们输入的数据太过单一,只测试了1种输入输出的情况;

下面我们将着手解决数据输入太过单一的问题。我们将使用Scenario Outline技术。

什么是Scenario Outline

什么是Scenario Outline呢,我们不妨先去命令行里看一下,在命令行中输入

java -cp "jars/*" cucumber.api.cli.Main --i18n zh-CN

这将得到cucumber关键字的翻译:

| feature | "功能" |

| background | "背景" |

| scenario | "场景", "剧本" |

| scenario_outline | "场景大纲", "剧本大纲" |

| examples | "例子" |

| given | "* ", "假如", "假设", "假定" |

| when | "* ", "当" |

| then | "* ", "那么" |

| and | "* ", "而且", "并且", "同时" |

| but | "* ", "但是" |

| given (code) | "假如", "假设", "假定" |

| when (code) | "当" |

| then (code) | "那么" |

| and (code) | "而且", "并且", "同时" |

| but (code) | "但是" |

我们可以看到scenario outline被翻译成了场景大纲或者是剧本大纲。简单来说,场景大纲可以理解为同一个场景同一部戏,内容都一样,台词也一样,只是换了不同的演员来演。每个场景大纲定义了不同的演员列表,该场景的台词是一样,演员的动作也相同,只是每次换不同的演员去表演。所谓铁打的营盘流水的兵。因此,场景大纲里定义了几组演员,这个场景就要演几次。

cucumber的场景大纲不是用来定义演员的,而是用来定义数据的。大纲里定义几组数据,那么该场景就要跑几次。

增加Example

现在我们给我们的feature增加1组测试数据:

#language: zh-CN

功能:任务管理

场景大纲: 完成任务

假设 我的任务清单里有个任务

当 我完成件任务之后

那么 我还剩下件未完成的任务

例子:

| total | finished | left |

| 3 | 1 | 2 |

| 5 | 1 | 4 |

运行一下

run

我们发现cucumber报错了:

#language: zh-CN

功能: 任务管理

场景大纲: 完成任务 # todo.feature:5

假设我的任务清单里有个任务

当我完成件任务之后

那么我还剩下件未完成的任务

例子:

场景大纲: 完成任务 # todo.feature:12

假设我的任务清单里有3个任务 # TodoStep.iHaveSomeTasks(int)

当我完成1件任务之后 # TodoStep.iFinishSomeTasks(int)

那么我还剩下2件未完成的任务 # TodoStep.iLeftSomeTasks(int)

场景大纲: 完成任务 # todo.feature:13

假设我的任务清单里有5个任务 # TodoStep.iHaveSomeTasks(int)

java.lang.AssertionError: expected:<3> but was:<5>

at org.junit.Assert.fail(Assert.java:88)

at org.junit.Assert.failNotEquals(Assert.java:834)

at org.junit.Assert.assertEquals(Assert.java:645)

at org.junit.Assert.assertEquals(Assert.java:631)

at step_definitions.TodoStep.iHaveSomeTasks(TodoStep.java:15)

at ?.假设我的任务清单里有5个任务(todo.feature:6)

当我完成1件任务之后 # TodoStep.iFinishSomeTasks(int)

那么我还剩下4件未完成的任务 # TodoStep.iLeftSomeTasks(int)

Failed scenarios:

todo.feature:13 # 场景大纲: 完成任务

2 Scenarios (1 failed, 1 passed)

6 Steps (1 failed, 2 skipped, 3 passed)

0m0.166s

java.lang.AssertionError: expected:<3> but was:<5>

at org.junit.Assert.fail(Assert.java:88)

at org.junit.Assert.failNotEquals(Assert.java:834)

at org.junit.Assert.assertEquals(Assert.java:645)

at org.junit.Assert.assertEquals(Assert.java:631)

at step_definitions.TodoStep.iHaveSomeTasks(TodoStep.java:15)

at ?.假设我的任务清单里有5个任务(todo.feature:6)

看起来密密麻麻,实际上的意思就是场景大纲里的第二组数据报错了,我们的TodoList的实现无法满足第二组数据,想想这也是应该的。

在这里要解释一下例子这个关键字。例子在英文里叫Example,是feature关键字。紧跟在例子后的一半都是1个数据列表,从上文可以看到,一目了然。数据列表有表头,表后下面的行跟着的是测试数据。

Scenario Outline运行流程

Scenario Outline的运行流程就是先从例子里读一行数据,然后根据该数据的column也即是表头,在steps里找到相应的字段,用具体的数据进行替换。例子里有2行数据这个Scenario就会运行2次。因此我们上面的feature文件实际上是这样运行的:

假设 我的任务清单里有3个任务

当 我完成1件任务之后

那么 我还剩下2件未完成的任务

假设 我的任务清单里有5个任务

当 我完成1件任务之后

那么 我还剩下4件未完成的任务

重构并让用例通过

我们的用例已经测试出TodoList类的缺陷了,是时候重构一下了,先重构TodoStep.java文件

// TodoStep.java

package step_definitions;

import cucumber.api.java.zh_cn.*;

import cucumber.api.PendingException;

import static org.junit.Assert.*;

import implementation.TodoList;

public class TodoStep {

TodoList todo;

@假设("^我的任务清单里有(\\d+)个任务$")

public void iHaveSomeTasks(int totalTasks) throws Throwable {

// Write code here that turns the phrase above into concrete actions

todo = new TodoList();

todo.setTotalTaskCount(totalTasks);

}

@当("^我完成(\\d+)件任务之后$")

public void iFinishSomeTasks(int finishedTasks) throws Throwable {

// Write code here that turns the phrase above into concrete actions

todo.finishTask(finishedTasks);

}

@那么("^我还剩下(\\d+)件未完成的任务$")

public void iLeftSomeTasks(int leftTasks) throws Throwable {

// Write code here that turns the phrase above into concrete actions

assertEquals(todo.getRestTasksCount(), leftTasks);

}

}

我们这里假设TodoList有1个setTotalTaskCount方法,该方法用来设置当前TodoList中task的总数。另外我们还把假设中的断言给去掉了,这是因为如果假设中有断言,那就意味着你连前置条件都不信任,既然前提条件都不能保证,那么下面的步骤就没有太多意义了,所以去掉会让步骤定义更加的符合逻辑。

再重构TodoList.java文件

package implementation;

public class TodoList {

int totalTaskCount;

int finishedTaskCount;

public TodoList() {

totalTaskCount = finishedTaskCount = 0;

}

public int getTotalTaskCount() {

return totalTaskCount;

}

public void setTotalTaskCount(int count) {

totalTaskCount = count;

}

public void finishTask(int count) {

finishedTaskCount = count;

}

public int getRestTasksCount() {

return totalTaskCount - finishedTaskCount;

}

}

代码很简单,就不一一解释了。

运行一下

compile && run

结果如下,所有的step都pass了。

#language: zh-CN

功能: 任务管理

场景大纲: 完成任务 # todo.feature:5

假设我的任务清单里有个任务

当我完成件任务之后

那么我还剩下件未完成的任务

例子:

场景大纲: 完成任务 # todo.feature:12

假设我的任务清单里有3个任务 # TodoStep.iHaveSomeTasks(int)

当我完成1件任务之后 # TodoStep.iFinishSomeTasks(int)

那么我还剩下2件未完成的任务 # TodoStep.iLeftSomeTasks(int)

场景大纲: 完成任务 # todo.feature:13

假设我的任务清单里有5个任务 # TodoStep.iHaveSomeTasks(int)

当我完成1件任务之后 # TodoStep.iFinishSomeTasks(int)

那么我还剩下4件未完成的任务 # TodoStep.iLeftSomeTasks(int)

2 Scenarios (2 passed)

6 Steps (6 passed)

0m0.133s

总结

从上面的例子里我们就可以看出自动化对生产力的提升帮助巨大。假设我们还需要测试100组数据,如果人肉手点的话,那么执行用例的人自然是痛不欲生,而且我们也没有办法完全保证数据输入的准确性,毕竟老虎也会有打盹的时候,何况是人。但是如果用自动化测试的话,增加数据无非就是在数据表中增加一些行,工作量不是特别大,而且可以比较容易的检查出数据是否准确。

像这种以增加输入输出数据的方式增加用例的测试用例设计方法,我们可以称之为数据驱动。

下一节我们将进一步的实现项目工程学上的自动化,我们将使用maven来搭建cucumber项目。

cucumber java从入门到精通_cucumber java从入门到精通(4)Scenario Outline及数据驱动...相关推荐

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

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

  2. 超硬核Java工程师学习指南,真正的从入门到精通,众多粉丝亲测已拿offer!

    最近有很多小伙伴来问我,Java小白如何入门,如何安排学习路线,每一步应该怎么走比较好.原本我以为之前的几篇文章已经可以解决大家的问题了,其实不然,因为我之前写的文章都是站在Java后端的全局上进行思 ...

  3. java从入门到精通教程_Java从入门到精通全套教程

    Java从入门到精通全套教程视频简介: 随着电脑网络的飞速发展,对现代计算机软件人才的要求越来越高.既要求他们横向掌握多门主流的编程语言,又需要同时至少对1-2门编程技术有深刻的认知.特此,星火视频为 ...

  4. 从入门到精通的Java进阶学习笔记整理,不愧是大佬

    前言 一位小伙伴准备了许久的阿里Java面试,原以为能够顺利拿下offer,但在第三面还是被摁在地上反复摩擦,丧气一段时间后,小伙伴调整了心态重新尝试了一下,最终拿下了offer,今天小编把这位小伙伴 ...

  5. 最新Java学习路线,java入门到精通,Java自学者的福利

    前言 如果你想自学 Java,认真看完本文,你以后的职场生涯至少少走1年弯路. 行业现状 程序员现状 由于程序员的薪水比较高,最近几年有很多其他专业的人涌进了程序员行业,加速了这个行业的内卷,但是据某 ...

  6. java从入门到精通_Java---开发从入门到精通,分享视频学习教程

    主要内容 Java中的方法 递归算法 接收键盘中的输入 面向对象的本质 我的第一个类:Student 垃圾回收机制 构造方法 方法的重载 static声明的静态属性和静态方法 this关键字的使用 笔 ...

  7. 30自学java之路_从小白到精通的java自学之路

    原标题:从小白到精通的java自学之路 随着互联网行业的高速发展,编程无疑越来越深入人心.而Java是当前世界非常流行的编程语言之一,代表着很高的薪资和很好的待遇.现在社会也确实有很多人渐渐的对jav ...

  8. java教程孙鑫_[Java基础] 孙鑫老师JAVA无难事视频教程 最适合java入门学习打基础的课程 附源码...

    资源介绍 课程介绍 由孙鑫老师亲自授课录制.内容涵盖面广,从入门到精通,授课通俗易懂,分析问题独到精辟,学员通过本套光盘的学习,能够快速掌握Java编程语言,成为Java高手. 由孙鑫老师亲自授课录制 ...

  9. 孙鑫java基础视频教程_孙鑫老师JAVA无难事视频教程 最适合java入门学习打基础的课程 附源码讲义 12课...

    课程介绍 由孙鑫老师亲自授课录制.内容涵盖面广,从入门到精通,授课通俗易懂,分析问题独到精辟,学员通过本套光盘的学习,能够快速掌握Java编程语言,成为Java高手. 由孙鑫老师亲自授课录制.内容涵盖 ...

最新文章

  1. java b kb mb gb 转换_java 上传文件大小转换为 GB/MB/KB/B
  2. W - Pasha and Phone CodeForces - 595B (收益颇丰的数学题
  3. SQL Server 查询基础
  4. SQL语言之DQL语言学习(八)多表查询/链接查询 SQL92学习
  5. C++之const修饰得到是谁
  6. Android学习笔记(5)----启动 Theme.Dialog 主题的Activity时程序崩溃的解决办法
  7. 图像局部显著性—点特征(Fast)
  8. 如何在S/4HANA里创建Custom Business object并实现自定义逻辑
  9. datatables.js 简单使用--多选框和服务器端分页
  10. java中广告维护轮播图怎么做_Banner广告轮播图
  11. 蚂蚁集团换帅!胡晓明辞任 CEO
  12. redis数据结构存储Linked List设计细节(redis的设计与实现笔记)
  13. 日常生活小常识100条
  14. Ubantu系统中安装360Wifi步骤
  15. 香帅的北大金融学课笔记18 -- 监管、创新、危机
  16. Emlog模板 简洁大气留白风格源码资源站
  17. 最小攻击超过最大攻击_贪婪洞窟攻击力解析 最大攻击与最小攻击对比分析
  18. S4 BOM批量修改
  19. docker学习篇(二)---- 基础篇
  20. win10搜索计算机中所有excel,win10系统无法搜索到word、excel等文件内容的处理技巧...

热门文章

  1. SQL Server中的约束(六种约束)
  2. linux+gunzip解压命令,Linux gunzip命令解析 gunzip解压文件的方法
  3. Python编程从入门到实践:动手试一试:5-1~5-13
  4. 爬虫实战1:爬取糗事百科段子
  5. 用4433法则+python代码筛选债券基金
  6. Python isdigit()方法能处理带符号的数字字符串么?
  7. 【4万字Linux线程解析】从0开始学习Linux线程
  8. 数学不好,可以当程序员么?
  9. JAVA基本框架搭建(Maven,jetty,Jod…
  10. SMBIOS信息概述 – DMI