单元测试的艺术
所有程序员都知道应该做单元测试!
然而很多人却没有做,原因是各式各样的。
就如Uncle Bob之前提到过的 The Little Mocker 中介绍Mock和Stub的关系一样, 这本书对一些容易混淆的概念作出了解释,也解释了实现的单元测试的难度和好处。
优秀单元测试的特质
- 自动化的代码
- 用自动化测试框架编写
- 容易编写
- 运行快速
- 能由开发团队里的任何人重复运行
三大支柱
- 可读性
- 可维护性
- 可靠性
用TDD的开发方式比较容易实现优秀的单元测试。
测试命名的规范
[UnitOfWork]_[Scenario]_[ExpectedBehavior]
尽量不用[Setup]/ @Before 和 [Teardown]/ @After ,用工厂方法代替。
用存根(Stub)破除依赖
找到或者创造合适的中间层,在运行代码中注入存根。
存根(Stub) vs 模拟对象(Mock)
存根不会让测试失败,不会在里面写断言,仅仅用来模拟各种场景。
模拟对象类似存根,但它能进行断言。 一个测试不能有多个模拟对象,它之外的伪对象都应该是存根。
隔离框架
隔离框架很酷,关键在于如何自如地使用它们。
如果超过5%的测试使用模拟对象(而非存根),那就可能“过度指定”了,会导致代码既不可读,又容易失败。
隔离框架分2种:
- 受限
- 不受限
选择框架时要理解一个框架的能力和局限,大多数的受限框架在运行时生成和编译代码。
测试层次和组织
- 无论何种测试,都应该自动化
- 把集成测试和单元测试分开
(慢和快测试分开,创造绿色安全区) - 按项目和类型组织测试
- 使用测试类层次
- 把API介绍给队友
在组织中引入单元测试
不要疏远可能帮助自己的人,准备好进行一场艰难的战斗: 理解影响力的力量。
遗留代码
要了解各个组件的依赖数、逻辑量以及在项目中的优先级,从简单的开始。
处理遗留代码的时候,带上一瓶好伏特加也是个不错的主意。 (=_=)