深入单元测试系列之二,TDD和单元测试

测试驱动开发(TDD)的全称是Test-Driven Development。上一篇文章中,介绍了Kent Beck,他是极限编程的创始人,测试驱动开发是在极限编程中引入的一种编程实践和技术,是敏捷软件开发的关键实践之一。测试驱动开发是先编写测试案例,然后再实现代码。

Kent和Erich Gamma在1997年10月搭乘同一趟航班飞往美国亚特兰,参加一年一度的OOPSLA(Object Oriented Programming Systems Languages &Applications)会议。OOPSLA会议是美国计算机协会(ACM)举办的一个年度性会议,第一届是1986年在美国波特兰市举办,最后一期是2010年,后来成为了SPLASH (Systems, Programming, Languages, and Applications: Software for Humanity)的一部分,是一个IT行业牛人云集的会议,会议的主题主要是编程界的前沿技术,具有一定的学术性,比如1997年有一个关于Java(Type Parameterization)泛型的话题,直到2004年的JDK5发布,才正式的支持泛型。

Kent和Erich还是是Eclipse的主要架构设计者,Erich 2011年加入微软,负责Visual Studio Code的开发。Erich最著名的书是《设计模式》,就是我们通常说的23种经典设计模式的作者之一。在飞机上,两个人一拍即合,完成了最初的JUnit版本,是仿照SUnit的Java版本,SUnit是Smalltalk编程语言的测试框架,Junit框架至今已经进化到第五代了,生态圈也非常的完整。

Kent 2011年加入Facebook,担任软件技术教练,负责公司工程师文化的落地和推广,帮助新员工掌握并使用相关的技能。通过敏捷和自动化测试的实施,Facebook可以做到每周甚至每日发布,而且大多数团队没有专职的QA人员。Kent 2019年加入了一家创业型SaaS软件公司Gusto担任Fellow,做着赋能的事情,该公司是人力资源领域的SaaS独角兽,员工1400人,估值约38亿美金。

近些年,有人在TDD 的基础上提出了ATDD(Acceptance Test Driven Development)的概念,包括 BDD(Behavior Driven Development)和 Consumer-Driven Contracts Development 等编程实践和技术,把TDD分为狭义的和广义的,狭义的 TDD是指UTDD(Unit Test Driven Development),而广义的 TDD 是指 ATDD。本文中所指的TDD是指的UTDD,即单元测试驱动开发。

测试驱动有三层含义:
第一层是驱动设计,测试代码相当于是实现代码的客户端,编写测试案例的时候,会迫使开发人员去思考,代码的接口和方法应该如何设计,如何组织代码,如何被客户端调用等;当然这里的驱动设计是值得商榷的,设计形式是多种的,比如UML辅助,也可以采用领域驱动设计(DDD)的方法。
第二层是驱动代码质量,测试案例来源需求,单元测试通过,就可以证明在测试案例覆盖的范围,代码是经过测试的,从而做到测试和BUG修复的循环变得最小,快速获得反馈提升效率,同时代码的质量也会有保障,未来改动代码的时候,运行单元测试,可以及时发现问题,起到防止代码被改坏的作用;
第三层是驱动重构和改进设计,因为有单元测试的保障,开发人员在重构代码之后就不用担心改出问题。

TDD的编码步骤

image

TDD 的基本流程是:红,绿,重构。

  • 根据需求编写一个测试用例
  • 红:运行测试,失败
  • 实现代码刚好能让测试通过
  • 绿:运行测试,成功,失败进入上一步
  • 重构:识别坏味道,用重构手法修改代码
  • 绿:运行测试,成功,失败回到上一步

是否采用了TDD的开发方式就不用Debug了呢?

答案是否定的,开发过程中可能遇到测试失败,但是也无法一下看出代码问题的情况,还是需要使用Debug模式调试代码,查看运行是的变量和代码执行路径。

对于TDD,也有很多常见的观点:

  • 业务需求变化太快,测试代码改来改去浪费时间;
  • 开发时间紧,项目发布都是倒排的计划,根本没时间写TDD代码;
  • 不知道怎么写单元测试,Debug就很好用;
  • 代码从来不进行重构;
  • 使用Mock和Stub技术,UT没有办法测试集成后的功能,业务价值不大;

对于TDD一直存在争议,牛人也是褒贬不一,Kent Beck、Martin Fowler、David Heinemeier Hansson(RoR之父)在2014年有过一场关于TDD的讨论,主题是“TDD已经死了吗?”,有兴趣的可以听一下对话。Is TDD Dead
David他之后又写了“ TDD 已死 - 测试永生”和“测试引起的设计伤害”这两篇文章来对这一主题进行了扩展。

我个人的观点就是,既然测试很重要,那测试是必须的,至于是先测试还是后测试,在开发过程中一定交织在一起的,不用过于纠结是不是TDD。以下是几个实践的建议:
1、不写单元测试,不允许提交代码
2、提交代码前需要本地运行单元测试确保通过
3、持续集成平台需要持续运行单元测试
4、不过度追求100%测试覆盖率

我们一直在实践中探寻更好的软件开发方法,身体力行的同时也帮助他人。
我们的探寻还尚未结束,TDD 只是我们在这一历程中所寻找到的其中一种,还存在其他方式供我们去继续寻找。

以下内容是经典的TDD的练习题目,FizzBuzz游戏,大家感兴趣可以练习并实践一下,参考视频。

为什么别人写代码那么快?这篇文章是熊节(重构一书译者)举办的程序员练功房培训班里面的作业视频,最快的1分15秒完成了编程,大部分能够在5-10分钟内完成编程。

我自己录制的视频,采用了传统的编码方式,用时6分23秒,差距还是有的。
测试驱动开发示例

想象一下你上小学五年级,在课程结束前的五分钟,你的数学老师说要带着大家玩一个小游戏。他将依次指着每个学生,并要求他们从一开始依次报数。第⼀个被指着的学⽣说“1”,第⼆个被指着的学⽣说“2”,如果数字可被三整除,则不能说数字,要说“Fizz”,如果数字被五可整除,则说“Buzz”。
游戏开始了,⽼师的⼿指向⼀个个同学,他们开⼼地喊着:“1!”,“2!”,“Fizz!”,“4!”,“Buzz!”……终于,⽼师指向了你,时间仿佛静⽌,你的嘴发⼲,你的掌⼼在出汗,你仔细计算,然后终于喊出“Fizz!”。运⽓不错,你躲过了⼀劫,游戏继续进⾏。
为了避免在⾃⼰这⼉尴尬,我们想了⼀个作弊的法⼦:最好能提前把整个列表打印出来,这样就知道到我这⼉的时候该说什么了。全班有33个同学,游戏可能会玩2到3轮。

任务:写⼀个程序,打印出从1到100的数字,将其中3的倍数替换成“Fizz”,5的倍数替换成“Buzz”。既能被3整除、⼜能被5整除的数则替换成FizzBuzz。

样本输出:
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
...

第二阶段,新需求:

  • 如果⼀个数能被3整除,或者包含数字3,那么这个数就是“Fizz”
  • 如果⼀个数能被5整除,或者包含数字5,那么这个数就是“Buzz”

参考:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容