落地TDD,需要知道的

TDD

TDD是个好东西,推广时,需从Why/what/how来说服别人,结合最近看的一些资料,来说明一下问题:

1、单元测试的理由


《[高效程序员的45个习惯:敏捷开发修炼之道》中已经对于单元测试好处做了一些说明:

- 单元测试能及时提供反馈。你的代码会重复得到锻炼。若修改或者重构,作为防护网会检查是否破外了已有功能。快速得到反馈,并容易修复他。他是重构的基础。

- 单元测试让你的代码更健壮。测试帮助你全面的思考代码的行为,帮你联系正面,反面以及异常情况。

- 单元测试是有用的设计工具。有助于简单设计,注重实效。

- 单元测试是让你自信的后台。你测试代码,了解不同条件下的行为,面对压力找到自信。

- 单元测试解决问题的探测器。提供发现问题和解决问题的方法。

- 单元测试是可信的文档。 学API时,可以帮你提供精准和可靠的文档。是程序员之间的语言。

- 单元测试学习工具。帮你了解API行为。

2、TDD的风格


参考文章《TDD 真的能带来好设计么?》(原文:http://codurance.com/2015/05/12/does-tdd-lead-to-good-design/)中介绍TDD有两种主要的风格,它们在何时进行设计有着相当显著的区别。

2.1 古典派

古典派是由Kent Beck开创的原本风格,也被称为底特律式TDD

2.1.1 主要特点

- 设计在重构阶段发生。

- 一般来说测试是基于状态的测试。

- 在重构阶段,由测试驱动的单元可能会分化为多个类。

- 极少使用Mock技术,除非是要与现存系统隔离。

- 在编码前不进行设计方面的思索。设计完全是从代码中浮现出来的。

- 是避免过度设计的极佳方法。

- 基于状态的测试以及无前置设计,使得这种风格更容易理解和采用。

- 常常结合简单设计四规则一起使用。

- 当我们知道输入和期望的输出,但是不清楚实现可能是什么样的时候,很适合使用这种方式进行探索。

- 在我们无法借助行业专家和行业语言(比如数据转换,算法等)的情况下很有帮助。

2.1.2 问题

- 单纯为了测试暴露状态。

- 相比由外而内风格,重构阶段通常更大。后面会详细介绍由外而内风格。

- 当新的类在重构阶段浮现出类时,被测的单元就会超出一个类。如果我们单单看那个测试的话,这没什么问题,然而,当新的类浮现出来后,它就有了自己的生命。它会被程序的其他部分复用。当这个类演化时,可能会破坏其它不相关的测试,因为那些测试使用了它们实际的实现而不是mock对象。

- 经验不足的练习者往往会跳过重构,也就是设计改进的阶段,导致开发进程变为 红灯—绿灯—红灯—绿灯—...—红灯—绿灯—大重构。

- 由于探索式的特点,测试驱动下的类产生于“我想我们需要一个有这样接口的类”。可能无法和系统的其它部分很好地对接。

- 有可能会缓慢费事。我们常常一开始已经知道被测的类不应该有这么多的职责,古典派的建议是等待重构阶段,只在确实有必要时才抽出其它类。对于初学者来说这可能是个好建议,对更有经验的程序员纯粹是浪费时间。

2.2 由外而内

由外而内TDD,也被称作伦敦派或者mock式,是由一些XP实践先驱接受和发展出的风格。随后它启发产生了BDD。

2.2.1 主要特点

- 不同于经典派,由外及内TDD为我们如何着手测试驱动代码做出了规定:从外(接到外部输入的第一个类)到内(各个将会实现系统需要的一个单一特性的类)。

- 一般从一个验收测试开始,验收测试用来检验是否整个功能工作。验收测试也为实现进行了向导。

-验收测试的失败会告知我们功能还有某些部分没有实现的信息(数据没有返回,消息没有送入队列,数据没有存人数据库等等),从中我们可以开始进行单元测试。第一个被测的类负责接收外部的请求(比如一个控制器,队列监听器,事件接收器,组件入口等)。

- 鉴于我们知道我们不会在一个类里实现整个程序,我们会假定被测试类会需要一些合作类。然后我们在测试里验证被测类与其合作类之间的协作。

- 通过被测类需要调用合作类公开方法来完成的各种事,可以识别出合作类。合作类的名字和方法名应该来自于行业语言中的名词和动词。

- 当一个类被完全测试后,我们选取一个合作类(此时应该还没有进行实现),并采用与上一个类相同的方式,通过测试驱动它的行为。这就是我们叫它由外而内的原因:我们从靠近系统输入的地方(外部)通过不断识别合作类,逐步向程序内部推进。

- 设计起始于红灯阶段,也就是开始写测试时。

- 测试测的是行为和协作,而非状态。

- 在重构阶段对设计进行完善。

- 每个合作类以及它的公开方法都是为了给已有的客户类提供服务的,这使得代码可读性很高。

- 相比经典式方法,由外而内式的重构阶段要小得多。

- 提高了封装性,因为不需要仅仅为了测试而暴露状态。

- 更符合“tell, don't ask”设计方法。

- 更符合面向对象编程的原本理念:测试是关于对象间发送的消息,而非检测对象的状态。

- 适用于商业应用,从user story和验收条件中可以获得名词和动词。(作为类名和方法名)。

2.2.2 问题

- 对于初学者来说很难接受,因为需要更高层次的设计能力。

- 开发者从代码中无法得到反馈来创建合作类。他们需要通过写测试来使合作类显现出来。

- 不成熟的创建合作类有可能导致过度设计。

- 不适用于探索式的工作,以及不特定于user story的行为(数据转换,算法等)。

- 设计能力糟糕的话可能会导致mock对象爆炸式的激增。

- 基于行为的测试要比基于状态的测试难写。

- 在写测试的时候需要具备DDD(领域驱动设计)以及其他设计技能,包括简单设计四规则。

2.3 小结

虽然两者各有优缺点,考虑维护性和效益问题,一般考虑从外而内,选择接口稳定,并且具有业务含义的用力进行测试。

3、落地TDD遇到的问题


推广TDD,一般阻力都比较大,主要有以下方面:

3.1 质量意识

传统的软件研发模式,对于软件质量,常常偏重于软件的外部质量。检查开发人员的的工作效益或者质量,主要是测试人员发现的缺陷数。这种模式下,形成的惯性思维认为开发人员不适合做测试,主要有测试人员进行质量保证。

推行TDD,以为不仅仅要关注外部质量,又要关注内部质量。当有开发人员进行TDD时,因为代码的可测试性问题,会导致单元测试举步为艰,这也成为阻力。如果代码的内部质量低下,但在足够覆盖率的保护下,使得重构变得更为简单。

 3.2 业务分析和拆解能力

在TDD时,如果按照标准的敏捷模式运行,需要有完整的故事和AC。如果BA角色缺失或者PO对于AC描述不清,在编写TDD的用例(To-do list)时,将成为问题。业务的分解需要分为三个层次,即业务价值—>业务功能—>业务实现。

 3.3 测试先行的开发习惯

养成一个习惯需要二十一天,改变一个习惯需要六十天。 要让开发人员改变习惯需要一个过程。记得自己改变的过程中,强制自己通过截屏方式记录每个过程。一周下来,基本可以做到测试先行和三步提交原则。

3.4 Clean Code和重构

TDD的核心是红——绿——蓝。蓝色意味着重构。重构是TDD非常重要的一环,它直接关系到TDD开发出来的代码质量。没有好的重构能力,TDD就会有缺失。实施TDD,需要开发人员具备Clean Code和重构的能力。

3.5 业务测试框架

良好的测试框架,使用测试用例编写和测试数据管理变得容易。在测试框架的付出是需要值得。自己的团队在推广TDD,也是得意于良好的测试用例,从而保证4个月时间,测试用例从200增长到1000以上,覆盖率从20%达到39%以上。

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