在目前比较流行的敏捷开发模式(如极限编程、Scrum方法等)中,推崇“测试驱动开发(Test Driven Development,TDD)”——测试在先、编码在后的开发实践。TDD有别于以往的“先编码、后测试”的开发过程,而是在编程之前,先写测试脚本或设计测试用例。TDD在敏捷开发模式中被称之为“测试优先的编程(test-first programming)”,而在IBM Rational统一过程(Rational Unified Process,RUP)中被称为“测试优先的设计(test-first design)”。所有这些,都在强调“测试先行”,使得开发人员对所做的设计或所写的代码有足够的信心,同时也有勇气进行设计或代码的快速重构,有利于快速迭代、持续交付。重构的前提就是测试就绪(testing is ready),在这样的前提下,重构的风险就很低,否则就有比较高的风险。

TDD具体实施过程,可以看作两个层次,如图1所示:

  1. 在代码层次,在编码之前写测试脚本,可以称为单元测试驱动开发(Unit Test Driven Development,UTDD)
  2. 在业务层次,在需求分析时就确定需求(如用户故事)的验收标准,即验收测试驱动开发(Acceptance Test Driven Development,ATDD)。
图1  TDD的两个不同层次

先来讨论UTDD,如图2 所示。在打算添加某项新功能时,先不要急着写程序代码,而是将程序可能会碰到的特定条件、边界值、上下文等想清楚,为待编写(类或方法)的代码先写好测试脚本。然后,利用集成开发环境或相应的测试工具来执行这段测试用例,结果自然是通过不了(失败)。利用没有通过测试的错误信息反馈,了解到代码没有通过测试用例的原因,有针对性的逐步地添加代码。为了要使该测试用例通过,就要补充、修改代码,直到代码符合测试用例的要求,获得通过。测试用例全部执行成功,说明新添加的功能通过了单元测试,可以进入下一个环节。这样的流程也适合代码修改或重构,真正执行时,也不会严格按照这样的流程去做,但最基本要求是:先写好测试脚本(代码),再写产品代码并通过测试。按照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的更多相关文章

  1. 《sort帮你排序》-linux命令五分钟系列之二十六

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...

  2. 《sed的流艺术之四》-linux命令五分钟系列之二十四

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...

  3. 《sed的流艺术之三》-linux命令五分钟系列之二十三

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...

  4. 《sed的流艺术之二》-linux命令五分钟系列之二十二

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...

  5. 《sed的流艺术之一》-linux命令五分钟系列之二十一

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...

  6. 《paste命令》-linux命令五分钟系列之二十

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...

  7. JVM内存管理之GC算法精解(五分钟让你彻底明白标记/清除算法)

    相信不少猿友看到标题就认为LZ是标题党了,不过既然您已经被LZ忽悠进来了,那就好好的享受一顿算法大餐吧.不过LZ丑话说前面哦,这篇文章应该能让各位彻底理解标记/清除算法,不过倘若各位猿友不能在五分钟内 ...

  8. 五分钟搭建一个基于BERT的NER模型

    BERT 简介 BERT是2018年google 提出来的预训练的语言模型,并且它打破很多NLP领域的任务记录,其提出在nlp的领域具有重要意义.预训练的(pre-train)的语言模型通过无监督的学 ...

  9. 五分钟学Java:如何才能学好Java Web里这么多的技术

    原创声明 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 系列文章介绍 本文是<五分钟学Java>系列文章的一篇 本系列文章主要围绕Java程序员必须掌握的核心技能,结合我个人三年 ...

随机推荐

  1. Python六剑客

    1.切片 切片:截取可迭代对象的部分内容(list,tuple,dict,set,str) 2.列表解析式 列表解析式可以快速的生成一个列表 不带if条件的: 格式:[expression for i ...

  2. Windows server 2012文件服务器配置

    文件服务器的管理   Windows server 2012提供了易于使用的管理工具,让系统管理员更有效的管理服务器的资源. 安装文件服务器管理工具 添加角色-安装管理器 安装完成后直接可以在工具中打 ...

  3. 计算几何-Dot-Vector

    This article is made by Jason-Cow.Welcome to reprint.But please post the article's address. 看了书,然后码 ...

  4. InkWell容器 和 官方自带日期组件 和第三方 日期格式转换组件

    带点击事件的容器 InkWell( child: Text('时间'), onTap: _showTimePicker,),   Flutter 日期和时间戳 日期转化成时间戳: var now = ...

  5. Codeforces Round #622 (Div. 2)

    A: 题意: 有ABC的三种菜,现在有a个A,b个B,c个C,问能组成多少种不同菜单 思路: abc都大于等于4,肯定是7种,给abc排个序,从大到小举例删减 #include<bits/std ...

  6. QT写的一个小工具:阿里云MQTT连接参数生成器.

    一.工具介绍. 最近在研究MQTT协议联网的一些问题,现在主流的物联网平台都支持MQTT协议. 在做阿里云平台连接测试的时候,连接参数的生成没有好用的工具, 所以就自己写了一个. 这个工具主要用于阿里 ...

  7. SpringCloud-粪发涂墙90

    https://mp.weixin.qq.com/s/UNm8cBw4TKq4OobVKHUBXA 邻国相望,鸡犬之声相闻,民至老死不相往来.这个世界被小诸侯给切的七零八落,一锅乱麻. 而现实是,我的 ...

  8. 「JSOI2015」串分割

    「JSOI2015」串分割 传送门 首先我们会有一个贪心的想法:分得越均匀越好,因为长的绝对比短的大. 那么对于最均匀的情况,也就是 \(k | n\) 的情况,我们肯定是通过枚举第一次分割的位置,然 ...

  9. dfs序与求子树子节点(染了色)的个数

    https://blog.csdn.net/hpu2022/article/details/81910490 https://blog.csdn.net/qq_39670434/article/det ...

  10. win10下Ubuntu18.04安装的简单教程

    win10下Ubuntu18.04安装的简单教程      操作系统:windows    软件:Vmware15.      一.下载 Ubuntu18.04镜像   Ubuntu18.04镜像下载 ...