lcov分支覆盖率的分析和总结

覆盖率显示规则

一行从左到右分别万代表:

1.代码行号(空白代表分支显示不过来产生换行)

2.分支覆盖情况 3.该行调用次数 4.该行源代码以及行覆盖情况

其中,分支覆盖情况详细介绍如下:

中括号代表生成的一对子分支,+代表该子分支被覆盖,-代表该子分支未覆盖,但对应的另一分支被覆盖,#代表两个子分支均未被覆盖。

以if(condition)为例,如果该condition没有子条件,即不是其他条件"与"、"或"产生,那么会产生两个分支,即condition == true condition == false,若只能满足condition == true 或false,则分支覆盖结果为[+ -]或[- +],如果多次调用时condition == true 或false都能满足,则分支覆盖结果为[+ +]。如果condition == true或false都不能发生,那么覆盖结果为[# #](虽然在最简单的条件下这个结果并不会发生)。

行覆盖情况详细介绍如下:

如果该行代码被覆盖到,则其底色为蓝色,没有被覆盖到,则底色为蓝色,若该行是上一行代码的续行,或为return 语句、class声明等,其底色为白色,代表不会进行检测。注意,没有被覆盖的行不会产生分支。

除了常见的逻辑判断外,还有很多产生分支的情况,并且难以完全覆盖,总结如下:

一、 常见逻辑判断

1. if (condition1) - elseif (condition2) - else [if(true)和if(false)除外]

2. for(init;condition/incre)/while(condition) [while(true)、while(false)和for(init;;incre)等没有条件判断除外]

3.条件运算符 condition ? exp1 : exp2

4.switch - case

5.多条件的与或。常见的为return (mulit-condition) ,例如return (x==0 || x==1)。

二、空间/文件管理操作

解析:可能存在操作没有权限、内存分配失败等情况。

1. new /delete 操作符

2. 文件操作:打开、关闭、输出等

例如

cv::FileStorage cameraSettings{std::string(camera_file), cv::FileStorage::READ};
cameraSettings.isOpened()

cameraSettings.close()

以及fprintf等。

3.memcpy

三、宏/内联函数自带的判断

如果宏/内联函数声明中自带判断,那么预处理时会在调用处原地展开,最好的做法是用普通函数代替宏/内联函数,这样不会在每个调用的代码段都产生分支。

四、字符串转换

1.char *到String类

String类的构造函数如下:(加粗部分含有判断)

basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())

      : _M_dataplus(_M_local_data(), __a)

      { _M_construct(__s, __s ? __s + traits_type::length(__s) : __s+npos); }

char *转String时会判断char *是否为nullptr,即自带一个判断。

2.String类到char *

与char *到String类相似。

五、类成员函数调用

即使成员函数内部没有判断,也没有返回值。

六、cpp文件末尾。

七、其他库函数调用。

但是一般情况下只能使用测试样例实现对常见逻辑判断的覆盖,以及使用普通函数代替宏或者内联函数来提高分支覆盖率,其他情况下不能覆盖,只能给予说明。

复杂情形:

一、

if ((std::abs(p.arr[2]) < 1e-10) 
&& (std::abs(p.arr[3]) < 1e-10) 
&& (std::abs(p.arr[4]) < 1e-10) 
&&(std::abs(p.arr[5]) < 1e-10))

该判断共四个子条件,但lcov显示共10个分支,包括四个子条件分别成立和不成立,共八个分支,外加总条件,即这些子条件的与的成立和不成立两个条件,共十个分支:

  1. std::abs(p.arr[2]) < 1e-10 成立
  2. std::abs(p.arr[2]) < 1e-10 不成立
  3. std::abs(p.arr[3]) < 1e-10 成立
  4. std::abs(p.arr[3]) < 1e-10 不成立
  5. std::abs(p.arr[4]) < 1e-10 成立
  6. std::abs(p.arr[4]) < 1e-10 不成立
  7. std::abs(p.arr[5]) < 1e-10 成立
  8. std::abs(p.arr[5]) < 1e-10 不成立
  9. std::abs产生,不明
  10. std::abs产生,不明

二、

if ((!load_with_general_format) &&       
loadCameraModelParametersWithSVFormat(
std::string(camera_file), camera_param)) 
{return camera;}

看起来平平无奇只有两个子条件,其实蕴藏杀机,衍生出了14个分支,分别为:

  1. load_with_general_format == true
  2. load_with_general_format == false
  3. 函数loadCameraModelParametersWithSVFormat返回值为true
  4. 函数loadCameraModelParametersWithSVFormat返回值为false
  5. std::string(camera_file)中camera_file[char *]为空
  6. std::string(camera_file)中camera_file[char *]不为空
  7. 函数调用,不明
  8. 函数调用,不明

以及最后6个分支为函数loadCameraModelParametersWithSVFormat内部有三个if实现,即6个分支,共14个。

  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
lcov是一个测试覆盖率工具,用于分析程序代码的测试覆盖情况。分支覆盖率lcov分析报告中的一个指标,用于衡量程序中用于控制流程的分支语句是否被测试覆盖到。 分支覆盖率指的是程序中的条件分支语句,例如if语句或者switch语句中的不同分支,是否被测试用例执行到。通过lcov生成的分析报告,我们可以看到每个分支被执行的次数,以及被执行的比例。 分支覆盖率是一个重要的测试指标,因为分支语句是程序中的关键控制点,测试覆盖到所有的分支意味着对程序的各种情况都进行了测试。通过分支覆盖率,我们可以判断测试用例是否覆盖到了所有的分支情况,并据此得出测试的全面性和有效性。 分支覆盖率计算是通过在编译过程中添加额外的代码实现的,这些代码用于跟踪分支的执行情况。在程序执行过程中,这些额外的代码会记录每个分支被执行的次数。通过分析这些记录,lcov可以计算出每个分支覆盖率。 在使用lcov进行测试覆盖率分析时,我们可以根据分支覆盖率的报告来判断测试用例的覆盖情况,并找出原程序中哪些分支没有被覆盖到。这样我们就可以根据这些信息来优化测试用例的编写,提高程序的稳定性和质量。 总的来说,lcov分支覆盖率是一项有助于衡量测试用例的全面性和有效性的指标,可以帮助开发者找出程序中未被覆盖到的分支情况,并据此来进行测试用例的优化和改进。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值