原则上,工程中所有函数均应进行单元测试以最大程度地提高软件可靠性、鲁棒性。
在实际项目中往往会考虑时间成本,很难面面俱到。经过几个月的项目实践总结了一些简单经验和体会,在此分享。
1 “不作为”函数不测
“不作为”函数具备以下特点:
(1)仅具有传送功能;
(2)功能单一;
(3)无判断分支与循环语句。
这类函数一般负责不同类之间的交互,直接或间接地调用相关类以完成通知或回调任务,
并不直接对所在类内成员数据进行修改,一般来说,对其单测并无实质性效果,反而耗费宝贵的时间。
例如以下函数:
void func(Type data)
{
//传送至消息队列
send( msg_queue, data );
}
对于这类函数无需测试,主要通过走查形式进行评审即可,但其内部调用
的函数可能有必要测试。
2 多类耦合
对于待测类与多个类相互关联的情况,对其单元测试往往难以下手,可视情况采用以下两种方法之一。
(1)关联类全mock
该方法要求对所有与待测类关联的类进行mock,这是gtest等测试框架的推荐方案,其优缺点如下:
优点:
- 对其他服务的依赖性较低
- 测试覆盖面广,代码可测性强
缺点:
- 需要实现所有Mock类,测试成本高,难度大
- 对第三方服务进行mock比较困难
因此该方法适用于代码质量要求极高且开发时间充裕的项目。
(2)直接使用关联类
该方法不对相关类进行mock,通过直接使用相关源代码编译链接的方式对待测类进行单测,优缺点如下:
优点:
- 简单方便,省时省力
缺点:
- 关联类bug会影响待测类,从而增加定位bug难度
3 认清代码覆盖率
高覆盖率是发现程序问题的手段而非目标。
测试目的是发现潜在问题。
通过单元测试可以找到哪些代码未被覆盖,此时正确的做法是分析这段代码可能存在的问题,进而评估其需被覆盖的必要性,对于有必要覆盖的再设计测试用例。