TDD 测试驱动开发
Kent Beck 提出的TDD。
TDD有三层含义:
Test-Driven Development
Task-Driven Development
Test-Driven Design
编码方式:
- 先分解任务,分离关注点
- 列 Example,用实例化需求,澄清需求细节
- 写test case,只关注需求,程序的输入输出,不关心中间过程
- 写实现,不考虑别的需求,用最简单的方式满足当前这个小需求即可
- refactor,用手法消除代码里的坏味道
- 写完,手动测试一下。有问题补个用例,修复
- 转QA,有问题,补用例,修复
红:写一个失败的测试,它是对一个小需求的描述,只需要关心输入输出,这个时候根本不用关心如何实现。
绿:专注在用最快的方式实现当前这个小需求,不用关心其他需求,也不要管代码的质量多么惨不忍睹。
重构:既不用思考需求,也没有实现的压力,只需要找出代码中的坏味道,并用一个手法消除它,让代码变成整洁的代码
重构:既不用思考需求,也没有实现的压力,只需要找出代码中的坏味道,并用一个手法消除它,让代码变成整洁的代码
注意力控制
人的注意力既可以主动控制,也会被被动吸引。注意力来回切换的话,就会消耗更多精力,思考也会不那么完整。
使用 TDD 开发,我们要主动去控制注意力,写测试的时候,发现一个类没有定义,IDE 提示编译错误,这时候你如果去创建这个类,你的注意力就不在需求上了,已经切换到了实现上,我们应该专注地写完这个测试,思考它是否表达了需求,确定无误后再开始去消除编译错误。
人的注意力既可以主动控制,也会被被动吸引。注意力来回切换的话,就会消耗更多精力,思考也会不那么完整。
使用 TDD 开发,我们要主动去控制注意力,写测试的时候,发现一个类没有定义,IDE 提示编译错误,这时候你如果去创建这个类,你的注意力就不在需求上了,已经切换到了实现上,我们应该专注地写完这个测试,思考它是否表达了需求,确定无误后再开始去消除编译错误。
好的单元测试应该符合几条原则:
- 简单,只测试一个需求
- 符合 Given-When-Then 格式
- 速度快
- 包含断言
- 可以重复执行
>真的什么都会测吗?连 getter 和 setter 也会测试吗?
Kent Beck 说:公司请我来是为了实现业务价值,而不是写测试代码。
所以我只在没有信心的地方写测试代码。
>TDD 要不要做提前设计呢?
Kent Beck 不做提前设计,他会选一个最简单的用例,直接开写,用最简单的代码通过测试。逐渐增加测试,让代码变复杂,用重构来驱动出设计。
TTD中要求写完一个test case后,在代码里做到快速实现。我觉得这一点也很关键。先用hard code做出来,然后测试通过后,再去关注具体实现。代码的每次改动后就跑一次测试。完全省去了,写完一长串代码后,跑不起来,再加断点debug省时间和精力。
实例请参考:https://www.jianshu.com/p/62f16cd4fef3
在视频里看到现场写代码,才能对TDD有形象和深刻的理解