近期针对TDD,进行了理论学习及实战,完全吸收需要花费不少时间,故文字记录以便加深、巩固及后续学习。本博文主要记录TDD理解及实战感想。
- 什么是TDD?
TDD(Test-Driven Development)是测试驱动开发的英文简称,是敏捷开发中的一项核心实践和技术,也是一种设计方法论。TDD的原理是在开发功能代码之前,先编写单元测试用例代码,然后只编写使测试通过的功能代码,通过测试来推动整个开发的进行。
- 为什么TDD?
TDD一种浅显的认知:先写测试用例,再写代码,通过用例看护代码质量,就叫TDD。其实不然,TDD的核心在于--分离关注点:
- 关注点WHAT:通过测试用例的撰写、设计,理清需求、验收条件,明确系统/模块要做什么,制定契约;
- 关注点HOW:代码层面如何实现。
大多数开发惯有思维:忽略WHAT,直接站在实现(即HOW)的角度思考问题,而TDD能够强制开发人员分离关注点为WHAT、HOW两步,先站在验收/使用者角度思考问题,明确模块输入、输出(即验收标准),辅助设计,划清职责、边界,再考虑如何基于设计实现代码。基于分离关注点,可带来如下好处:
- 从使用者角度抽象服务接口,隔离实现,使接口设计更加合理、稳定;
- 优先明确模块输入、输出,有助于划清模块职责、边界,后续易通过打桩等测试手段隔离依赖,保证模块独立可测;
- 提前明确验收标准,理清需求,既可以防止功能缺失,又可以避免开发盲目的设计/实现无明确来源、需求的功能,减少不必要开发。代码写的越少,功能越简单,错误越少,稳定性越高;
- 基于验收角度设计的用例,只关注需求,程序的输入、输出,不关心中间过程,能够保证测试用例的稳定性,避免因为代码实现的变动而导致用例频繁变动。
- 如何做TDD?
针对TDD落地,最关键步骤:
- 任务分解:将复杂问题拆解为可验证、相互独立、易读易懂的简单任务。任务分解因人而异,原则:拆解到自己认为简单、可控制即可(eg:15分钟内可利用上下文图将任务表达出来)。任务拆解是TDD中最难的部分,可能需要领域驱动设计/面向对象设计等方法,对系统进行抽象、分解;

- 明确验收标准:明确各简单任务验收标准(即WHAT)。
- 严格遵守以上两点,直到最终分解的任务可验证、相互独立。现实开发过程中,离代码实现越近时,开发就越急于编码,而跳过部分任务分解、验收标准的明确,导致最终实现代码耦合、函数职责不单一等问题。
- 实践总结
- TDD用例、设计很难一步到位,需要代码实现的检验
培训过程中,老师要求严格按照TDD流程,如下图所示:
- 先做任务分解,然后基于分解的任务,写测试用例,测试fail;
- 再写代码实现,测试pass;
- 对代码进行重构。

通过近期个人实践发现,设计、用例和代码实现在不断迭代循环,很难做到用例、设计一步到位。实际操作中,均是在先大致考虑并输出设计、测试用例后,通过代码实现检验类图、测试用例的正确性,不断迭代。实际操作中,可通过补充时序图、上下文图等方法帮忙理清思路,尽量提高前期设计的正确性,避免后续实现时返工。
培训期间,老师如此严格要求的目的可能在于:将TDD的执行流程推向极致,让大家有个深刻印象吧!!
- 可以不用TDD,但是验收角度思考不能少
通过前面小节介绍可知,TDD最核心的价值在于:分离关注点,使开发者站在验收角度思考问题,明确WHAT。
实际工作中,不见得必须使用TDD,但是作为开发人员,在承接新需求、设计、编码任何环节,面临新问题,都能够注意站在验收角度去思考问题,明确WHAT,再说HOW。
- 上下文图
上下文图主要用于表示已被分解的简单任务,将函数的输入、输出(细化到参数类型、结构)图形化,类似于时序图的简化版,有助于问题的拆解以及表达,适合内部交流使用。不过上下文图非标准图形,具体表达元素只要组织内部达成一致,形成统一语言即可:
- 函数名:带命名的表示过程的方框;
- 输入:指向方框的箭头;
- 输出:背离方框的箭头。
如下图所示,用户流量套餐系统中的查询套餐业务,上下文图将简单任务分解为:
- commandLine(命令行)
输入:用户指令(类型:字符串);
输出:用户套餐信息(类型:字符串)
- Systemcontrol(系统控制)
输入:NA,命令行系统解析指令后,直接调用systemcontrol对应处理,无输入
输出:用户套餐信息(类型:字符串),后面依次类推,不再逐个描述
- QueryPackageInfo(查询套餐信息)
- GetPackageInfo(获取套餐信息);
- PackageFormat(套餐信息格式化);
- GetMenuInfo(获取主菜单);

在使用上下文图时,若上下文图嵌套的模块层次太深时,会导致图形过于复杂,此时可基于场景对系统进一步拆分,保证上下文图的简洁、易读。如上面例子所示的“用户流量套餐系统”可基于用户场景分为:查询流量套餐、注册用户、订阅流量套餐、取消流量套餐四个场景。应针对四种场景逐个画上下文图,而不是将四个场景融合在一个上下文图中。要谨记上下文图要简洁、易读,一个简单的衡量方法:15分钟内可完成的上下文图认定为符合简洁、易读原则。