《Cucumber:行为驱动开发指南》章节试读

出版社:人民邮电出版社
出版日期:2013-6-27
ISBN:9787115318855
作者:[英]Matt Wynne,[挪]Aslak Hellesy
页数:272页

《Cucumber:行为驱动开发指南》的笔记-第72页 - 富有表现力的场景

1. 去除杂乱与重复
使用: scenario outline (场景轮廓) 与 数据表 来组织场景。
使用: Background 关键字来描述公共步骤。
对于Background 的使用,首先,它必须用在“Scenario”或“scenario outline”前,其次,由于它是公共场景的抽象,请保持它的简洁,毕竟你不可能将一个有 10句话的公共场景时时记住吧?
不要在特性文件中加入太多的技术细节,而是描述行为,技术细节由实现者考虑。
表格可以跟在任意步骤后面,表格不关心空格,会无视。
Scenario outline (场景轮廓)
意思是操作步骤是相同的,只是输入值与期望值不同。使用scenario outline (场景轮廓)+Examples的配合,在Examples下列举所有可能的数据场景。场景会循环执行Examples下的每行数据。
使用<...>将占位符引起来,表示它是一个参数,尖括号里的名称与表的列标题相同,如:
Then 维度列表包含:<学生编号>,<学生名称>清单
| 学生编号 | 学生名称 |
| 1 | 张三 |
| 2 | 李四 |
可以有多个实例表:Examples
从而你可以对你的数据场景进行分组(这里注意,Examples并不是说例子举的越多越好,要举核心实例,典型实例)。
文档字符串:
可以使用 """ 三个引号来表示一段文本的引用。
让特性文件有条理
1. 使用标签
标签使用 @ +描述构成
标签一般加在场景(Scenario)上
如果需要给特性文件中的每一个场景都加上标签,则加上Feature关键字上
标签可以加多个,如:
@a @b @c
Scenario: xxxx
2. 使用文件夹管理
顾名思义

《Cucumber:行为驱动开发指南》的笔记-第220页 - 第十四章:引导Rails

此章节略过。

《Cucumber:行为驱动开发指南》的笔记-第138页 - 第八章:支持代码

辅助代码(World模块)
指步骤定义和系统之间的代码,它包含了许多辅助方法,作为特性文件与系统代码的隔离层,起解耦作用。
简单设计标准:
1. 通过所有的测试
2. 展示所有的意图
3. 不包含任何重复
4. 使用尽可能少的类和方法
展示所有的意图,本质上是对用词的精准性的追求,要求给事物命名要规范,要切合需求,不产生二义性。
使用capybara来模拟请求,进行自动化接口测试
钩子!//@Before 和 @After需要特别注意提,它是全局的,会在每个场景中都执行。
如果我们只想在某个特性文件中使用它,则需要使用带标签的钩子。
如:
@Before(value = {"@a", "@b"})这就要求在编写特性文件时,加@Feature 头上加上标签@a 或 @b
步骤定义是全局的!!!!
并且没有办法把步骤定义的范围降到特定的场景中(当然,牛逼到修改它的实现不算)。
其实这也是发明者用心良苦,想在Cucumber中,任何相同的句子,只能表示一种意思,这样也能避免重复实现。

《Cucumber:行为驱动开发指南》的笔记-第198页 - 第十二章:测试RESTWeb服务

进程内的测试,通过Rake-test在Ruby中进行测试
还有一个更好的方法是,在与测试系统集成在一起然后直接调用Controller层的接口方法,绕过REST接口,直接测试方法。

《Cucumber:行为驱动开发指南》的笔记-第153页 - 第九章:处理消息队列和异步组件

1. 如何测试异步代码?
首先,异步代码与测试进程是处于不同的进程中,那么,如何确保,Then执行时,正好异步操作也执行完毕?如果运气好,或是异步代码执行非常快,会在Then执行时,正好逻辑完成,于是通过,但不是每次都能运气好,这种场景称之为"闪烁的场景"
可以使用以下方式测试异步代码:
a. 通过监听"发布-订阅"通道,监听事件来同步。当然,这里需要有一个超时机制来保证,测试不会一直等待下去。
b. 如果无法监听时,可以使用轮询的方式来测试,如果在某个超时范围内,没有出现预期的正确结果,则测试失败。(这种方式有一个缺点:如果给定是100,处理完以后,还是100,那么,怎么知道系统有处理?针对这种场景,需要引入一个中间环节,把变化的过程记录下来)
Cucumber的目的是为了交流系统的行为。
结论:
对于异步代码最好的测试方法是使用监听事件的方式。

《Cucumber:行为驱动开发指南》的笔记-第167页 - 第十章:数据库

1. Ruby的数据库连接库: ActiveRecord
诞生于:Ruby on Rails 框架
使用它,在创建Domain类时,不需要定义它的列(即字段)
约定优于配置的原则,对于表名和实体类,有这样的约定:accounts -> Account,同样的,widgets -> Widget
2. 用事务清理数据库
书上使用@Before 与 @After 来管理事务。但实际使用中,可以使用标签的方式来处理事务,结合Spring的事务管理,可以使代码更少更好。
总结:使用了数据库的业务代码在进行测试时,要保证数据库是干净的。清理库可以有两种方法,一是通过事务回滚(适用于单线程),二是通过Truncate数据表(适用于多线程)

《Cucumber:行为驱动开发指南》的笔记-第116页 - 第七章:步骤定义:内在篇

变形器和World块,略

《Cucumber:行为驱动开发指南》的笔记-第52页 - 步骤定义:外在篇

自动化验收测试通常会模拟用户与系统的交互。
让每个定义的步骤描述都是唯一的,因为实现代码会通过正则与描述文字严格匹配,如果同时匹配两个语句,则视为这两个步骤是完全相同的语义。
步骤需要匹配的文字会以高亮显示。
Given、When、Then这三个关键字,在Cucumber看来是相同的(都忽略),所以你可以乱用,甚至可以不用,直接写 * 即可。
如果某个步骤抛出了异常,否则Cucumber认为它是通过的,因此,在指示结果的步骤(一般是Then和And)中,要存在结果断言
捕获参数:
1. 在描述中直接获取参数,如:
Then "用户A"的用户名是"名称1"
用双引号来标识参数,在生成的实现方法中,使用 \”(.*)\“来匹配参数,得到参数值。
2. 对于需要使用到多个数据场景的情况,需要配合:Scenario Outline 与 Examples 配合
Examples 后可接数据表格,如下:
When 当<用户>进入组织<组织>,并且用户状态为<成员状态>
Examples:
| 用户 | 组织 | 成员状态 |
| 小一 | 组织A,组织B | 组织成员 |
| 小二 | 组织A | 已邀请 |
| 小三 | 组织A | 组织管理员 |通过"<>"来指定参数,在实现时,会从后面紧跟的表格中获取对应名称的参数值。拥有Outline与Examples的场景,会在当前场景中循环每一行数据。
3. 在定义后可以跟一个表格,用于向步骤定义传递一组参数数组When 当<用户>进入组织<组织>,并且用户状态为<成员状态>
| 用户 | 组织 | 成员状态 |
| 小一 | 组织A,组织B | 组织成员 |
| 小二 | 组织A | 已邀请 |
| 小三 | 组织A | 组织管理员 |
可以通过 DataTable 来获取这组参数。
定义中的参数个数,必须与实现方法中的参数个数相同。

《Cucumber:行为驱动开发指南》的笔记-第205页 - 第十三章:为遗留系统添加测试

1. 消灭Bug
系统中发现的Bug,很容易被翻译成Cucumber的用例
在翻译成特性文件后,需要同Bug提出人确认描述的行为是否与实际发生Bug时的情况相同
特性文件会预期的失败,则视为成功的捕捉到了Bug
OK,接下来的工作是把它弄绿吧
但是!
编写Cucumber文件时,请忘记Bug本身,特性文件始终是描述的系统的行为,是一份活文档。

《Cucumber:行为驱动开发指南》的笔记-第180页 - 第十一章:Cucumber命令行界面

使用 --help 查看命令行帮助
1. 标签过滤
--tags @tagName 可以执行某些tag
~@tag 波浪符号表示除tag之外的其它tag
@tag1,@tag2 表示执行这两个
--tags @tag1 --tags @tag2 表示tag1 和 tag2 的 并 的关系
2. 行号过滤
a.feature --line 45 -> a.feature:45 这两者等价,冒号后面可以接多个数字
会从指定的行执行到场景的结尾
3. 基于名称过滤
--name name
Rake 是ruby 构建工具的事实标准。

《Cucumber:行为驱动开发指南》的笔记-第21页 - Cucumber初体验

Cucumber的使用示例
1. 创建符合Gherkin语法,以.feature结尾的文本文件
2. 使用Cucumber支持的目录结构
3. 编写实验代码
Feature: 测试
Scenario: S1.新建度量,是否可新建成功并正确显示
Given 存在以下数据:
| 学生编号 | 学生名称 |
| 1 | 张三 |
| 2 | 李四 |
When 进行搜索
Then 维度列表包含:<学生编号>,<学生名称>清单
| 学生编号 | 学生名称 |
| 1 | 张三 |
| 2 | 李四 |
实现代码:
public class PlusFeature {
private HashMap<String, String> data = new HashMap<>();
@Given("^存在以下数据:$")
public void 存在以下数据(DataTable dataTable) throws Throwable {
List<Map<String, String>> dataMaps = dataTable.asMaps(String.class, String.class);
for (Map<String, String> dataMap : dataMaps) {
this.data.put(dataMap.get("学生编号"), dataMap.get("学生名称"));
}
System.out.println(this.data);
}
@When("^进行搜索$")
public void 进行搜索() throws Throwable {
//do search
}
@Then("^维度列表包含:(.*),(.*)清单$")
public void 维度列表包含_学生编号_学生名称_清单(String a, String b,DataTable dataTable) throws Throwable {
List<Map<String, String>> dataMaps = dataTable.asMaps(String.class, String.class);
}
}
右键点击 .feature 文件,执行,绿色成功,红色失败。

《Cucumber:行为驱动开发指南》的笔记-第33页 - Gherkin基础

原始需求:
系统输出一个正方形这种描述是模糊的,对于开发人员来说是不具备可实性的,至少是多意性的。
系统输出一个长为5CM正方形而这种描述是精确的,可直接开发,也是可验收的。
Gherkin是一种语法,它是以 .feature 为扩展名的一种文本文件,与markdown、YAML十分相似。
关键字(Gherkin的关键字,被翻译成40多种语言,可以让使用者以自己母语编写)列表:
Feature //特性,每个Gherkin的文件都必须使用Feature开头
Background //背景
Scenario //场景
Given //给定条件
When //当...时候
Then //结果
And //然后...
But //但是...
* //通配符
Scenario Outline //与Examples配合使用
Examples //例子
符合Gherkin语法的必须有以下三个关键字之一:Background //背景
Scenario //场景
Scenario Outline //与Examples配合使用
对于文件命名,惯例是使用小写,单词间使用 “_” 下划线进行隔开。
Given、When、Then 是场景发生的上下文,可以使用 * 来替换这些关键字。
And、But 是一个步骤
每个场景(Scenario)都必须是独立的,不与其它场景产生依赖,能独立运行的。
注释使用 ”#“ 号,# 号要顶格
使用#language 做为第一行,可以指定语言(事实证明可以直接写中文)

《Cucumber:行为驱动开发指南》的笔记-第1页 - 第1章 为何使用Cucumber

有时候拥有天才的想法的人,不一定也是一个天才的程序员,
那么,想法就需要传递,需要彼此沟通,通过Cucumber,试图让代码与需求远离误解。
自动化验收测试源于XP(极限编程),测试驱动开发实践(Test-Driven-Development TDD) 的实践。
单元测试保证你正确的编写软件,而验收测试保证你编写的是正确的软件。
活文档
Cucumber以传统规格的语言描述需求,不同点在于,它能在任何时刻运行测试,这意味着文档不再会慢慢过期,而是成为一种活文档,时刻反应项目的真实状态。
以下是一份Cucumber用例的栗子:
Feature: 注册 //特性,功能
//注册功能的Cucumber用例
Scenario: 使用手机号注册成功 //场景
When 输入<手机号>、设置<密码> //步骤
And 点击“获取手机验证码”
Then 手机号收到验证码
如何工作?
Cucumber使用一套Gherkin语法,如上述示例内容的文件被称之为特性文件,其中会定义系统在给定场景下,会如何工作,给定输入,并得出固定的输出。
特性文件中的 When、Then、And 等,被称之为步骤定义,步骤定义的名称会与实现代码的通过正则的方式严格匹配。
可以通过Tag 来给场景打标签,以便管理和执行一类场景。
Cucumber的场景是全局的,一个特性文件中的 步骤描述,不允许重复。
Cucumber的@before @after 方法也是全局的,会在任意一个Cucumber文件执行时都会被调用。

《Cucumber:行为驱动开发指南》的笔记-第93页 - Cucumber的觉问题与解决之道

Cucumber是一个”活文档“
它,既是 ”活“ 的。
又是 ”文档“。
活是指它是最新的,随需求而变化的,可自动测试。
文档是指它是可读的,能够用于大家有效的沟通。
数据嗓音
只关心核心测试点,比如想测试用户的密码找回功能,不应该提示,此用户是男或是女
声明式的描述
不要使用过细的技术语言去描述一个场景,如:
//填充单元格内容为:”aaa“
而应该使用更自然点的,描述系统行为的,比如:输入密码:aaa
这里不用管密码输入框到底是个单元格,还是一个其它的东西。
重复!
一般的,我们期望一个特性文件中的场景是没有重复的。
在同一个场景中,不同步骤之间也是没有重复的。
如果不同场景间有重复的内容,应该使用:
//Background || Scenario 这两个关键词进行抽象
值得注意的是,如果重复出现的频率挺高,也意味着特性文件的抽象程度不够。最要命的是,当系统的某个行为改变后,需要改动多个地方,而这多个地方,即难找,又难改。
最好的方式是同技术人员一道工作,得到他们的反馈。
编写Cucumber是,可读性压倒一切。
别闭门造车! 写案例时,听听想关人的想法,需求、测试、开发、管理and more...
Cucumber测试从本质上讲,就是对状态转换的测试,即有A(GIVEN),经过X(WHEN),然后B(THEN),由一个场景引起的状态变化,不能在另一个场景中有体现,不能干扰到另一个场景的测试。
场景要是独立的,可以确保场景执行时系统处于一个干净的状态!
试着清除那些:
1. 缓慢的特性
2. 间歇性失败的特性
3. 只有一部分人能读懂的特性
而且,问题只要一出现,就应该立即解决。
特性文件(用例)比实现代码更有价值(知道做什么,要比做出了什么的人更厉害)
怎么做?
1. 首先,写之前需要弄清系统的来龙去脉:它是做什么的,行为是怎么的?结果又应该是如何?
2. 然后用自己的语言加以提炼,注意不要重复的讲一个动作和重复的测一个行为。


 Cucumber:行为驱动开发指南下载 更多精彩书评


 

外国儿童文学,篆刻,百科,生物科学,科普,初中通用,育儿亲子,美容护肤PDF图书下载,。 零度图书网 

零度图书网 @ 2024