单元测试,指对软件中的最小可测试单元进行检查和验证,是保证函数和模块级别功能的重要手段。通过给代码单元添加合理的测试用例,可以验证代码功能,发现代码潜在问题,保障代码重构的正确性,提升对代码的信心。
单元测试的基本组成
模块化
模块化定义了我们如何组织单元测试,以文件为单位,以命名空间为单位,以类为单位,这些都是单元测试模块化的方式。比如CppUnit以类为单位组织测试用例,GTest通过宏TEST_F
组织测试用例。
夹具
夹具,选自机械加工的专用名词,表示加工前,对加工物进行固定。夹具可以用于组织测试用例,但更重要的是为模块里的每个测试添加一些在测试前后需要执行的通用操作。
测试方法
具体的测试用例执行体。
断言/期望
用于检查一个测试是否成功或失败,检查的项目包括但不限于:
- 是否返回某一具体的值
- 是否抛某种异常
- 是否不抛异常
- 某函数是否被调用,调用次数以及调用参数
Mock & Fake & Stub
- Mock 提前准备好并明确了某些期望的对象。通过检查对象的期望是否达成来进行交互测试
- Fake 不可用于生产环境的假对象,比如内存文件系统,用于隔离外部依赖
- Stub 桩对象,用于模拟某些操作或对象,隔离外部依赖,专注代码单元功能的验证
单元测试的基本准则
准确性
单元测试的断言或期望应准确,包含关键核心逻辑的验证,但也应该避免无效断言,防止代码迭代过程不必要的维护成本。
单一性
一个单元测试应该始终只关注一个函数的测试。
自动性
单元测试应该能够比较简单地自动化执行,方便进行CI集成。
完备性
单元测试应完备,覆盖基本的代码逻辑和分支。对于核心流程,希望能够达到 90% 的覆盖率,非核心流程要求 60% 以上。
可重复性
多次执行(任何环境任何时间)结果唯一,且可以重复执行。
可测性
表示代码的可测性,比如代码逻辑应该做到高类聚低耦合,依赖抽象而不是具体。常见的方式有:封装抽象、依赖注入。
网友评论