什么是测试驱动开发?
TDD 有广义和狭义之分,常说的是狭义的 TDD,即 UTDD(Unit Test Driven Development / 单元测试驱动开发)。
广义的 TDD 是 ATDD(Acceptance Test Driven Development / 验收测试驱动开发),包括 BDD(Behavior Driven Development)和 Consumer-Driven Contracts Development 等。
本文所说的 TDD 指狭义上的 TDD,即 UTDD。
TDD是测试驱动开发(Test-Driven Development)的英文简称,是敏捷开发中的一项核心实践和技术,也是一种设计方法论。TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码。
TDD 的思想
测试列表
对产品需求进行分析,采用分治思想,把需求拆分成一个个任务或者是一个个模块。从而产生测试列表,避免功能的疏漏。
测试驱动
利用测试来驱动开发,是 TDD 的核心。要实现某个功能、类或函数,应首先编写测试代码,只关注于需求及程序的输入输出,不关心中间过程。
小步迭代
TDD 讲求的小步迭代是写完一个测试再去写完一个实现,每个实现都是通过测试的。如此累加小胜为大胜,最后所有代码的收尾也不过是让最后一个测试通过而已。
及时重构
重构是 TDD 流程中非常重要的一环,它直接关系到 TDD 开发出来的代码质量。对设计结构不合理、重复等“坏味道”的代码,在测试通过后,应及时进行重构,简洁可用正是 TDD 追求的目标。
TDD 的流程
在这个闭环内,每一个阶段的输出都会成为下一个阶段的输入。
- Fails ——写一个功能最小完备的单元测试,并使得该单元测试编译失败
- Passes —— 快速编写刚刚好使测试通过的代码,不需要考虑太多,甚至可以使用一些不合理的方法。
- 重构——消除刚刚编码过程引入的重复设计,优化设计结构(减少耦合,增加内聚力)。
TDD 的难点
缺乏软件质量意识,外部质量体现在测试人员发现的缺陷数,内部质量体现在可读性、可重用性、可扩展性等。
缺乏分析需求并进行任务分解的能力,开发人员的习惯,看什么事情都会从技术实现的角度去思考。要实现一个网页,就会想到如何编写 JavaScript 来响应用户的动作,如何编写 CSS,而不会去思考用户体验和操作的流程。
任务分解可以分为三个层次,即业务价值 => 业务功能 => 业务实现。
测试先行的习惯难以养成
重构能力