测试驱动
红灯-绿灯-重构
测试驱动就是先写测试,这时测试是红灯,也就是不能通过;然后再写实现,这时测试变为绿灯,表示能通过了;最后重构优化代码,再次测试看是否有红灯
黑盒-白盒测试
黑盒测试就是不知道实现细节的测试,一般指功能测试
白盒测试就是知道实现细节的测试,一般指单元测试
测试就是可执行的文档,而TDD是创建和维护这种文档的最常用方式
单侧和集成测试
单侧要尽量覆盖所有情况,而集成测试只需验证各个部分是否打通,所以集成测试只需少许用例
TDD和非TDD的区别
未使用TDD的情况下,单元测试的主要目标是验证既有代码;而在TDD中,单元测试是预先编写的,其主要目标是定义需求和设计,而验证只是副产品。与实现后再编写测试相比,这样做的一个结果是产品质量更高。
Mockito、EasyMockit、PowerMock区别
一般用Mockito就够了;EasyMockit和Mockito用法差不多,只是稍微繁琐点;PowerMock用于那些不太容易Mock的情形,一般使用PowerMock说明代码实现已经很糟糕了
重构的原因有很多
- 代码难以理解
- 代码位置不合理
- 代码重复
- 名称没有清晰阐述意图
- 单个方法代码太多
- 类的功能太多
面相对象编程原则
- 单一职责原则:一个类应该只有一个导致它需要修改的原因。
- 开-闭原则:类应该对扩展是开放的,对修改是封闭的。这个原则最初由Bertrand Meyer提出。
- 里氏替换原则:这个原则是Barbara Liskov提出的,她指出,类应该能够被扩展它的类替换。
- 接口分离原则:提供多个具体接口胜过提供单个通用接口。
- 依赖倒转原则:类应依赖于抽象而不是实现,这意味着类依赖必须专注于做什么而不是如何做。
TDD最佳实践
命名约定
- 将实现代码和测试代码分开
- 将测试类和实现放在同一个包中
- 以类似于受测类的名称给测试类命名
- 给测试方法指定描述性名称
流程
- 先编写测试,再编写实现代码
- 仅在测试失败后,编写实现代码
- 每次修改实现代码后,都再次运行所有测试
- 仅当所有测试都通过后才编写新测试
- 仅当所有测试都通过后才重构
开发实践
- 编写让测试能够通过的最简单代码
- 先编写断言再编写操作
- 最大限度减少单个测试中的断言:断言失败时,其所属测试方法将停止执行。如果这个方法中还有其他断言,这些断言将不会执行,导致无法获得原本可用于调试的信息。
- 不要让测试依赖于其他测试:测试能以任何顺序运行,不管是运行全部还是部分,都将如此
- 测试运行速度必须很快:这样就能经常运行测试
- 使用测试替身:减少代码依赖并提高测试的执行的速度
- 使用@BeforeClass、@Before、@AfterClass、@After注解处理数据准备和数据清理操作
- 不要在测试中使用基类:让测试目的更清晰,一种常见的错误就是创建测试基类
工具
- 代码覆盖率和持续继承工具(CI)
- 结合使用TDD和BDD:TDD单元测试虽好,但很多情况下,这并不能提供项目需要的所有测试,BDD是实现面相客户的功能测试;
TDD致力于白盒测试,BDD致力于黑盒测试;
TDD提高代码覆盖率和提供快速反馈,BDD用于自动化验收测试;