前言
现在开发软件都讲敏捷开发,何为敏捷开发?敏捷开发是一种应对快速变化的需求的一种软件开发能力。它们的具体名称、理念、过程、术语都不尽相同,相对于"非敏捷",更强调程序员团队与业务专家之间的紧密协作、面对面的沟通(认为比书面的文档更有效)、频繁交付新的软件版本、紧凑而自我组织型的团队、能够很好地适应需求变化的代码编写和团队组织方法,也更注重做为软件开发中人的作用。但是现在敏捷开发又好几种方案,如:TDD
、BDD
、DDD
与 ATDD
。
几种模式的介绍
TDD:测试驱动开发(Test-Driven Development)
测试驱动开发是敏捷开发中的一项核心实践和技术,也是一种设计方法论,TDD首先考虑使用需求(对象、功能、过程、接口等)。主要是编写测试用例框架对功能的过程和接口进行设计,而测试框架可以持续进行验证。大行其道的一些模式对TDD的支持都非常不错,比如MVC和MVP等。
BDD:行为驱动开发(Behavior Driven Development)
BDD也就是行为驱动开发。这里的B并非指的是Business,实际上BDD可以看作是对TDD的一种补充,让开发、测试、BA以及客户都能在这个基础上达成一致,JBehave之类的BDD框架。
ATDD:验收测试驱动开发(Acceptance Test Driven Development)
通过单元测试用例来驱动功能代码的实现,团队需要定义出期望的质量标准和验收细则,以明确而且达成共识的验收测试计划(包含一系列测试场景)来驱动开发人员的TDD实践和测试人员的测试脚本开发。面向开发人员,强调如何实现系统以及如何检验。
DDD:领域驱动开发(Domain Drive Design)
DDD指的是Domain Drive Design,也就是领域驱动开发,DDD实际上也是建立在这个基础之上,因为它关注的是Service层的设计,着重于业务的实现,将分析和设计结合起来,不再使他们处于分裂的状态,这对于我们正确完整的实现客户的需求,以及建立一个具有业务伸缩性的模型。
TDD 实施方案
通过测试来推动整个开发的进行,但测试驱动开发并不只是单纯的测试工作,而是把需求分析,设计,质量控制量化的过程。
开发原则
先写测试代码后,再写功能代码。
- 根据需求文档编写测试代码,并非实现功能;
- 不要想一口吃成胖子,对大的功能块测试时应该先分拆成更小的功能块进行测试;
- 切记不能为完成功能而写代码,用尽可能简单的代码实现功能;
- 需求能够测试的,就写测试代码,不能测试的或觉得不需要测试的一律放弃;
- 在改/加任何功能代码前,一定要先想是不是要改/加测试用例;
- 功能/测试代码,结构不合理,重复代码等情况,在测试通过后,及时进行重构。
TDD的开发流程
- 分析并确定一个目标测试场景;
- 添加一个单元测试来验证该测试场景的输入输出;
- 运行该测试,得到失败的测试结果;
- 写最简单的功能代码来通过该测试;
- 再次运行该测试,看到测试通过;
- 进行代码重构,包括功能代码和单元测试代码;
- 重复以上步骤,直至开发完成。
TDD 的好处
- 降低开发者负担。通过明确的流程,让我们一次只关注一个点,思维负担更小。
- 保护网。覆盖完全的单元测试,对产品代码提供了一个保护网,让我们可以轻松地迎接需求变化或改善代码的设计。所以如果你的项目需求稳定,一次性做完,后续没有任何改动的话,能享受到 TDD 的好处就比较少了。
- 提前澄清需求。先写测试可以帮助我们去思考需求,并提前澄清需求细节,而不是代码写到一半才发现不明确的需求。
- 快速反馈。有很多人说 TDD 时,我的代码量增加了,所以开发效率降低了。但是,如果没有单元测试,你就要手工测试,你要花很多时间去准备数据,启动应用,跳转界面等,反馈是很慢的。准确说,快速反馈是单元测试的好处。
为什么很多人做 TDD 都做不起来?
- 不会合理拆分任务。
TDD
之前要拆分任务,把一个大需求拆成多个小需求;也可以拆出多个函数来。 - 不会写测试。什么是有效的单元测试,有很多人写测试,连到底在测什么都不清楚,也可能连断言都没有,通过控制台输出,肉眼对比来验证。好的单元测试应该符合几条原则:
- 简单,只测试一个需求
- 符合
Given-When-Then
格式 - 速度快
- 包含断言
- 可以重复执行
Given 一个上下文,指定测试预设;When 进行一系列操作,即所要执行的操作;Then 得到一系列可观察的后果,即需要检测的断言
- 不会写刚好的实现 很多人写实现的时候无法专注当前需求,一不小心就把其他需求也实现了,就破坏了节奏感。实现的时候不会小步快走。
- 不会重构。不懂什么是
Clean Code
,看不出Smell
,没有及时重构,等想要重构时已经难以下手了。不知道用合适的「手法」消除Smell
。 - 基础设施。对于特定技术栈,没有把单元测试基础设施搭建好,导致写测试时无法专注在测试用例上。拒绝拖延(感谢关注)