【转载】五分钟让你彻底了解TDD、ATDD、BDD&RBE
在目前比较流行的敏捷开发模式(如极限编程、Scrum方法等)中,推崇“测试驱动开发(Test Driven Development,TDD)”——测试在先、编码在后的开发实践。TDD有别于以往的“先编码、后测试”的开发过程,而是在编程之前,先写测试脚本或设计测试用例。TDD在敏捷开发模式中被称之为“测试优先的编程(test-first programming)”,而在IBM Rational统一过程(Rational Unified Process,RUP)中被称为“测试优先的设计(test-first design)”。所有这些,都在强调“测试先行”,使得开发人员对所做的设计或所写的代码有足够的信心,同时也有勇气进行设计或代码的快速重构,有利于快速迭代、持续交付。重构的前提就是测试就绪(testing is ready),在这样的前提下,重构的风险就很低,否则就有比较高的风险。
TDD具体实施过程,可以看作两个层次,如图1所示:
- 在代码层次,在编码之前写测试脚本,可以称为单元测试驱动开发(Unit Test Driven Development,UTDD)
- 在业务层次,在需求分析时就确定需求(如用户故事)的验收标准,即验收测试驱动开发(Acceptance Test Driven Development,ATDD)。
先来讨论UTDD,如图2 所示。在打算添加某项新功能时,先不要急着写程序代码,而是将程序可能会碰到的特定条件、边界值、上下文等想清楚,为待编写(类或方法)的代码先写好测试脚本。然后,利用集成开发环境或相应的测试工具来执行这段测试用例,结果自然是通过不了(失败)。利用没有通过测试的错误信息反馈,了解到代码没有通过测试用例的原因,有针对性的逐步地添加代码。为了要使该测试用例通过,就要补充、修改代码,直到代码符合测试用例的要求,获得通过。测试用例全部执行成功,说明新添加的功能通过了单元测试,可以进入下一个环节。这样的流程也适合代码修改或重构,真正执行时,也不会严格按照这样的流程去做,但最基本要求是:先写好测试脚本(代码),再写产品代码并通过测试。按照UTDD做法,不是先写产品代码的类,再写测试类,而是先写测试类,再写产品的类。
UTDD从根本上改变了开发人员的编程态度,开发人员不能在像过去那样随意写代码,要求写的每行代码都是有效的代码,写完所有的代码就意味着真正完成了编码任务。而在此之前,代码写完了,实际上只完成了一半工作,远没有结束,因为单元测试还没执行,可能会发现许多错误,一旦缺陷比较多,缺陷就比较难以定位与修正。UTDD在于促进开发人员思考功能特性的应用场景、异常情况或边界条件,写出更完善的代码,避免犯较多的错误。其次,也确保测试具有独立性,不受实现思维的影响,确保测试的客观、全面。这一点,对开发人员测试自己的代码是必要的。如果是倒过来,先写产品代码(即功能实现在前)再进行测试,那么测试会受实现思维影响。例如,我们自己写的文章自己检查,有时很明显的问题都发现不了,就是受实现思维的影响。一般来说(多数情况下),开发人员测试自己的代码有两个障碍:思维障碍和心理障碍。心理障碍是指开发人员对自己的代码不会穷追猛打,发现了一些缺陷,很可能会适可而止。我们知道,实际上缺陷越多的地方越有风险,越要进行足够的测试。最后,UTDD也确保所有代码的可测试性,每一行代码得到了测试,比较彻底地确保代码的(微观)质量。
许多研发人员不习惯UTDD这种模式,推行UTDD会遇到比较大的困难,那TDD的实施可以移到业务层,推行ATDD,即在设计、写代码之前,明确系统功能特性的验收标准,这比较容易推广实施。例如,在敏捷开发模式中,每个用户故事的描述过于简单,是不具有可测试性的。例如,开发一个在线旅游网,可以提供交通、酒店、门票等预定服务,有一个最基本的用户故事:
作为一个旅行者的用户,我想通过一次性的操作,快速删除事先预定的订单包(含飞机票、酒店和门票)
像这样的用户故事,如果不加验收标准,开发实现起来很容易,在数据库某个表中删除一条记录,在其它关联表上修改相应的标志位即可。但实际的业务不会那么简单,说取消就取消?不需要有一个时间提前量?取消一定成功吗?收不收相关的费用?是否需要线下处理的时间?是否需要通知用户?通过什么方式通知取消成功或失败?要回答这些问题,就是要给这个用户故事增加“验收标准”,如:
- 取消前,需要提醒用户再次确认
- 需提前24个小时取消
- 需要4个小时处理时间,才能知道取消成功与否
- 这类取消需要收取总金额10%的费用
- 不管取消成功与否,采用邮件和短信双重通知
- 用户事后可以查询取消的相关记录
- 需要保留客户和旅行网双向操作记录日志
这样,这个用户故事才具有可测试性,开发人员也会清楚如何实现这个用户故事,实现的结果和产品经理所期望的结果就不会有太大差异。
从ATDD演化出来一种具体落地的开发模式就是BDD(Behavior Driven Development,行为驱动开发)。BDD只是将验收标准更加明确化,可以看作是ATDD的实例化,即列出用户故事所可能遇到的应用场景,而且将这种应用场景的表达方式规定为GWT格式,即
BDD再往前推进一步,就是需求实例化(Requirements By Example,RBE),更加明确需求的具体表现。还是以上面用户故事为例,可以建立类似下列内容的需求实例化。
需求越明确,用户、产品经理、开发与测试等之间的理解就越一致(on the same page),更不产生偏差和误解,有利于开发和测试的工作。基于RBE,开发人员写产品的代码,测试人员可以独立写测试的代码,产品经理的工作也会变得轻松,不需要太多的解释、不需要回答开发和测试的各种问题。
- 从需求角度看,BDD和需求实例化比较彻底地明确需求,统一用户、产品经理、开发与测试等认识,让大家处在一个层面上,使研发工作更高效。
- 从测试角度看,需求即测试,产品的需求就是测试的需求,需求可以被执行,即一步到位,将需求变为自动化测试脚本,开发出来的功能特性随时可以被自动验证。
TDD一改以往的破坏性测试的思维方式,测试在先、编码在后,更符合“缺陷预防”的思想。这样一来,编码的思维方式发生了很大的变化,编写出高质量的代码去通过这些测试,在进行每项设计、写每一行代码时都要想想用户的真实需求、应用场景和一些例外等,确保实现的功能特性符合预期,并具有健壮性。测试,也从以前的破坏性的方法转移到一种建设性的方法中来。在这种积极心态的影响下,开发人员的工作效率和产品的质量都会有显著的提高,真正实现“质量是内建的(Quality is built in)”的目标。
本文转载自:https://mp.weixin.qq.com/s/KCrkL4NeuZeZvTu5Sc6B_g
【转载】五分钟让你彻底了解TDD、ATDD、BDD&RBE的更多相关文章
- 《sort帮你排序》-linux命令五分钟系列之二十六
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《sed的流艺术之四》-linux命令五分钟系列之二十四
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《sed的流艺术之三》-linux命令五分钟系列之二十三
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《sed的流艺术之二》-linux命令五分钟系列之二十二
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《sed的流艺术之一》-linux命令五分钟系列之二十一
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《paste命令》-linux命令五分钟系列之二十
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- JVM内存管理之GC算法精解(五分钟让你彻底明白标记/清除算法)
相信不少猿友看到标题就认为LZ是标题党了,不过既然您已经被LZ忽悠进来了,那就好好的享受一顿算法大餐吧.不过LZ丑话说前面哦,这篇文章应该能让各位彻底理解标记/清除算法,不过倘若各位猿友不能在五分钟内 ...
- 五分钟搭建一个基于BERT的NER模型
BERT 简介 BERT是2018年google 提出来的预训练的语言模型,并且它打破很多NLP领域的任务记录,其提出在nlp的领域具有重要意义.预训练的(pre-train)的语言模型通过无监督的学 ...
- 五分钟学Java:如何才能学好Java Web里这么多的技术
原创声明 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 系列文章介绍 本文是<五分钟学Java>系列文章的一篇 本系列文章主要围绕Java程序员必须掌握的核心技能,结合我个人三年 ...
随机推荐
- 13.56Mhz下50欧姆阻抗匹配简易教程
阻抗匹配(impedance matching) 主要用于传输线上,以此来达到所有高频的微波信号均能传递至负载点的目的,而且几乎不会有信号反射回来源点,从而提升能源效益.信号源内阻与所接传输线的特性阻 ...
- 使用webpack搭建vue环境
1.安装node.js,在官网下载,直接下一步,完成.nodejs里默认包含npm环境.国内安装包的速度太慢,建议使用cnpm淘宝镜像. npm install -g cnpm --registry= ...
- 第二十九篇 玩转数据结构——线段树(Segment Tree)
1.. 线段树引入 线段树也称为区间树 为什么要使用线段树:对于某些问题,我们只关心区间(线段) 经典的线段树问题:区间染色,有一面长度为n的墙,每次选择一段墙进行染色(染色允许覆盖),问 ...
- sql server获取查询时间
declare @d datetime set @d=getdate() /*你的SQL脚本开始*/ /*你的SQL脚本结束*/ select [语句执行花费时间(毫秒)]=datediff(ms,@ ...
- nfs 动态文件挂载读写权限设置
nfs 动态文件挂载读写权限设置 待办 ll 命令查看文件夹权限 参考设置共享文件夹https://www.linuxidc.com/Linux/2018-11/155331.htm
- 【SSH】spring 整合 hibernate
spring-hibernate-1.2.9.jar applicationContext.xml <bean id="sessionFactory" class=" ...
- 3种常见的CSS页面布局--双飞翼布局、粘连布局、左右两列布局
一.左右两列布局 1.代码如下,可先粘贴复制,自行运行 <!DOCTYPE html><html> <head> <meta charset="UT ...
- Go语言fmt.Printf使用指南
文章引用自 fmt fmt包实现了类似C语言printf和scanf的格式化I/O.主要分为向外输出内容和获取输入内容两大部分. 向外输出 标准库fmt提供了以下几种输出相关函数. Print Pri ...
- mysql 多次分组查询 数据最大的一行
SELECT B, D, Max(E)FROM `总表`WHERE B = '张士建'GROUP BY B, D 通过查询创建工具 编写查询语句
- C语言-实现矩阵的转置-随机函数产生随机数并赋予数组中-190222
//编写程序,实现矩阵的转置(行列互换). #include <stdio.h> #include <conio.h> #include <stdlib.h> ][ ...