“测试驱动开发(Test-Driven Development, TDD),以测试作为开发过程的中心,它要求在编写任何产品代码之前,先编写用于定义产品代码行为的测试,而编写的产品代码又要以使测试通过为目标。当我们在当前结构中找到最佳设计时,由于有足够的测试做保障,我们可以改动现有设计而不必担心破坏已完成的功能。使用这种开发方法,我们可以让设计更加优良,能编写出可测试的代码,同时还能避免在不切实际的假设基础上过度的设计系统。要得到这些好处,只需不断添加可执行测试,一步步地驱动设计,从而最终实现整个系统简单从好用。
何谓测试驱动开发
本文所说的TDD为单元测试驱动开发,是敏捷开发中的一项核心实践和技术,也是一种设计方法论。它的主要推动者是 Kent Beck。TDD的周期为“
测试-编码-重构”。测试先行,然后编码,最后设计。这种“设计后行”的思维方式有别于传统的“
设计-编码-测试”过程中的设计。这种事后设计的方法可称为
重构,表示把当前的设计转化成一个更佳的设计的过程。TDD的周期也可以用“
红-绿-重构”表示。
为何测试驱动开发
TDD是一种设计和开发方法,它能帮我们从项目开始就构建出可运行的软件,以增量的方式添加新功能,使软件在整个开发过程中都能工作良好。通过演进式设计,并且应用重构优化每一步的设计,我们可以防止代码质量随着时间推移而下降。高覆盖率的自动化单元测试又是软件的一道安全网。
TDD能帮我们正确的做事。
如何测试驱动开发
如何实施TDD,如何编写及通过测试,首先应从选择测试开始。
1、选择测试技巧
测试驱动开发与DevOps持续集成流水线结合
实施TDD的开发团队必须更频繁地与代码库保持同步,即持续集成。通过在开发者平台配置提交构建流水线和DOD质量门禁,有效检验TDD代码质量。当前已在项目中应用的指标包括:




一、增量式开发
所有敏捷软件开发过程,即要保证软件可随时可发布,且每天都能持续产生可部署的版本。下图描述的过程中,已完成且测试过的功能不断地累积。在每个时间点上,都只有少量的功能尚未完成或集成。很多项目会推迟交付日期或者交付质量不过关,是因直到最后一刻开发人员还在赶工。TDD可以解决这个问题。在TDD过程中,我们会小步地前进。每一小步都会产生一个工作良好的产品,每一步(以分钟计算)都会距离目标更近一些。二、重构以保持代码的健康
在小步前进的过程中,会不断扩展当前的设计以支持新功能,也会不断抛弃旧概念,引进新概念。这种情况下,软件的设计必然会变得很不一致。但通过重构,既可以演进式地设计,又能保持系统设计不出问题。具体重构方法可参考Martin Fowler的著作《重构:改善既有代码的设计》,本文仅介绍重构原则: 1、重构是种纪律严明的方法重构是指用某种严格的方式重构代码。重构或许会显著地改变当前设计,不过这种改变总是小步进行的,而且每一步都会验证代码的行为没有改变。 2、重构是种转换过程重构是两种状态间的转换。在初始状态中,代码的设计存在一定问题,而在目标状态中这些问题都已被修复。 3、重构会改变内部结构重构用于改变系统内部结构—代码,因此大部分重构手法都会涉及实现细节。 4、重构保持原有行为无论怎么修改代码,所变化的都只有代码的设计和内部结构,外部可见的行为和功能会维持原样。换言之,代码的用户应当对重构毫无察觉。如何确定重构没有改变系统的外部行为呢?测试可以确保软件正常运行。三、通过自动化测试保证软件正常运行
实施TDD过程中会编写大量的单元测试用例。而高覆盖率的单元测试可作为自动化回归测试,成为重构的安全网,保证重构工作不破坏已有的功能。 1、用自动化测试做保护 在整个开发过程中,回归测试会被反复执行许多遍,以保证系统已有功能正常运行。 自动化回归测试必须容易、快速地执行。 如果开发人员在每次微小变动后都运行自动化测试,可以精确地定位问题。 2、快速获得反馈通过与“持续集成”提交构建流水线结合,提交代码前运行与本次改动相关的单元测试,通过质量门禁判断代码能否提交版本管理系统,以快速反馈。

深入细节与整体考虑
整体优先:能够很快的验证总体设计,但推迟了细节方面的工作进度。
探索未知与轻车熟路
最大限度地获取价值与摘取现成的成果
走通基本功能路径(happy path)与先处理出错情况
伪实现
三角法
显而易见的实现
绝不跳过重构
尽快变绿
出错后放慢脚步


变更行覆盖率,阈值100%。
增量程序案例执行成功率,阈值100%。
增量技术规范问题,阈值为无主要、严重、阻塞问题。
增量Sonar问题,阈值为无严重、阻塞问题。
一、实施效果
抽取智能小象数据进行TDD效果分析如下: 1、手工测试发现缺陷数量逐月下降智能小象项目自7月版采用TDD研发模式以来测试质量有显著提升,每个版本的手工测试发现的缺陷数量在逐月下降。如下图:二、通过组织单元测试用例评审保证测试先行度
当前暂未启用开发者平台DOD门禁中的“测试先行”指标,而是在编码前组织由需求、开发、测试共同参与的UTDD Reviw单元测试用例评审,来确保测试先行。并使需求、开发、测试在研发前期对需求达成一致,减少返工率。三、在敏捷迭代研发模式中应用TDD
在迭代周期内采用TDD的研发模式,附聚富通项目组迭代内研发测试工作详情。四、下一步工作
1、将继续推动各研发部门需遵照中心测试驱动开发工作指引,做好单元测试脚本设计工作,夯实开发质量,组织好单元测试驱动开发方案与脚本的评审工作。2、对中心测试驱动开发实施情况进行评价,当前已有评价指标包括测试先行度、变更程序覆盖率(变更程序的行覆盖率、变更程序的分支覆盖率、核心程序的变更行覆盖率)、提交功能测试首日准入通过率等。3、调研验收测试驱动开发(ATDD)和行为驱动开发(BDD)。
END