1 术语定义

1.1. 代码覆盖率

      代码覆盖率 =代码的覆盖程度,一种度量方式。

1.2. 语句覆盖(StatementCoverage)

      又称行覆盖(LineCoverage),段覆盖(SegmentCoverage),基本块覆盖(BasicBlockCoverage),这是最常用也是最常见的一种覆盖方式,就是度量被测代码中每个可执行语句是否被执行到了

      这里说的是“可执行语句”,因此就不会包括像C++的头文件声明,代码注释,空行,等等。非常好理解,只统计能够执行的代码被执行了多少行。

      需要注意的是,单独一行的花括号{} 也常常被统计进去。

      语句覆盖常常被人指责为“最弱的覆盖”,它只管覆盖代码中的执行语句,却不考虑各种分支的组合等等。

1.3. 判定覆盖(DecisionCoverage)

      又称分支覆盖(BranchCoverage),所有边界覆盖(All-EdgesCoverage),基本路径覆盖(BasicPathCoverage),判定路径覆盖(Decision-Decision-Path)。它度量程序中每一个判定的分支是否都被测试到了。

1.4. 条件覆盖(ConditionCoverage)

      它度量判定中的每个子表达式结果true和false是否被测试到了。

1.5. 路径覆盖(PathCoverage)

      又称断言覆盖(PredicateCoverage)。它度量了是否函数的每一个分支都被执行了。 这句话也非常好理解,就是所有可能的分支都执行一遍,有多个分支嵌套时,需要对多个分支进行排列组合,可想而知,测试路径随着分支的数量指数级别增加。

       这是最强的覆盖,一般代码覆盖率工具都不支持,BullseyeCoverage也不支持。

2.BullseyeCoverage简介

      Bullseye Coverage 是Bullseye 公司提供的一款C/C++代码覆盖率测试工具。

      相对于Rational 的Pure Coverage,Bullseye     Coverage 支持的C/C++的编译器更多。除了支持各种Unix 下的编译器之外,在Windows 下支持VC、Borland C++、Gnu C++、Inter C++。

      提供的代码覆盖率是分支覆盖率而不是一般代码覆盖率,我个人认为分支覆盖率比代码覆盖率更好。

      我这里有破解版本和key,如果有人需要,欢迎向我索取。

3.BullseyeCoverage的安装

      因为有安装程序,所以安装整体来说比较简单。

      不过,有几个地方还是要注意,相关的截图如下。

      输入key,在license key输入框。

      设置cov文件路径,可以设置到一个你比较容易记住的路径下。这一步容易被忽略,导致最后都不知道cov文件在哪里。

      cov文件的作用后面会讲到。
      编译器选择,缺省会选择vc,但是建议把其他的几个主流的c++编译器也选上,这样可以识别更多类型的代码。

4.       BullseyeCoverage的使用

4.1.       在代码编译时如何使用?

      BullseyeCoverage安装好后,会在vc编译器中以插件的方式出现。

      在vc6的tools菜单中高亮显示部分,可以设置是否启用BullseyeCoverage。

      如果启用,则会在编译的时候,把相应的代码符号记录到cov文件中。

      可见设置cov文件路径的重要性,否则不好找。

      在vc2005中。

      特别提醒的是,BullseyeCoverage对业务代码逻辑无影响,只是在cov文件中记录了有关代码的函数、分支和条件判断等符号。

4.2.       在测试时如何使用?


1)  在测试机器上也必须安装BullseyeCoverage,安装方法跟上面介绍的一样。

测试的机器上是否安装vc编译器没有关系。

但是仍然要选择编译器类型,这样便于识别所选编译器产生的符号。

2)  把编译产生的程序复制到测试机器。

3)  用编译产生的cov文件覆盖测试机器上的cov文件。

4)  启动测试程序,开始测试不同的测试用例(主要是功能测试)。

5)  每测试完成一个功能case,都可以打开相应的cov文件,开始统计代码覆盖的情况。

      当然,做了多少测试后开始统计,完全由测试人员自行决定。

      打开一个cov文件如下。

6)  cov文件打开后的样子。
7)  其中打勾的表明该函数进入过,T表示ture,表示该条件分支被执行过,F表示false,表示该条件分支没有被执行过。

8)  统计情况请看下图中的底部的状态栏。
      其中有函数覆盖和未覆盖的百分比,条件或判断分支覆盖和未覆盖的百分比。

9)  这个工具还有一个强大的地方是,在上图的左侧是代码目录结构,可以分级统计代码覆盖率的情况。

10)值得注意的地方是:如果仅仅统计代码覆盖率的多少,不用提供源码。

但是如果要查看某个函数或条件分支的执行情况,则必须把测试产生的cov拿到有代码的机器上进行分析。

11)最好要注意的是:每次代码改动编译后,会产生新的cov文件,因此测试的版本和发布的版本必须一致。

12)还可以把统计结果导出成html或xml。
 

####################################################

BullseyeCoverage 工具主要用于检查C/C++程序的测试覆盖率,它可以帮助你:
1.识别在测试过程中没有完全执行的代码;
2.获取测试完整性相关的一些度量,来帮助你判断是否已经充分测试。
这对于手工测试和自动化测试来说都是有益的。

BullseyeCoverage 主要评估 条件/决策覆盖率,函数覆盖率。
有两个概念需要解释下,什么叫条件覆盖率,什么叫决策覆盖率?
条件覆盖率:度量每个子表达式结果的true和false是否被测试到。
决策覆盖率:又称分支覆盖率、路径覆盖率,度量程序中每个判定的分支是否被测试到。

注:对于决策和条件具体怎么来区分,举个例子:

  1. if (v1 == v2 && (v3 || v4))

对于决策来说,(v1 == v2 && (v3 || v4)) 这个表达式的true和false,是覆盖率评估的两个代码分支。
而对于条件来说,v3 、 v4、v1 == v2、 v1 == v2 && (v3 || v4) 这个四个表达式分别取true和false值,是评估的所有条件值。

具体的,对于某个程序,BullseyeCoverage 能够探测到代码的以下内容是否被覆盖到:
1.每个决策(判定)的ture和false;
2.每个条件的true和false;
3.switch语句的每个分支以及隐含的default分支;
4.try-block语句的分支;
5.函数和方法是否被调用;
6.每一个以花括号包含的语句块;
7.for语句的循环体。

BullseyeCoverage 使用步骤一般是:
1.安装BullseyeCoverage, 并使 BullseyeCoverage 工具可用,然后重新编译你的程序。
因为BullseyeCoverage工具是通过在程序中插桩代码来记录执行信息,所以需要使用工具自带的编译器来重新编译程序。
2.运行被评估程序。
3.产生和查看覆盖率评估报告。
4.重复执行第二和第三个步骤,直到满足你的测试为止。
---------------------------------------------------------------------------------------------------------------------------------------------
上面介绍了一些BullseyeCoverage 相关的理论知识,以下是一些使用实践(Linux系统)。
 

1.安装与设置
      具体的安装这里就不详述了,从官网下载相应的版本包(http://www.bullseye.com/cgi-bin/download.sh),make && make install 即可。
      完成后,bin目录下会有一些工具集,如果想使用方便些,把bin目录加入到PATH环境变量中,
      另外,还需要设置 COVFILE 环境变量,这个环境变量是一个文件路径,
      这个路径指示的文件(这里我们称它为覆盖率文件)用来存放工具获取的相关数据,可以设置为这样:
export COVFILE=`pwd`/test.cov 
      由于覆盖率文件中记录代码文件的名称是以覆盖率文件所在的目录作为相对地址的,
      所以执行以上命令的工作目录最好是在代码文件的最上层目录中,实际上就是把后续生成的覆盖率文件放置在此目录中。

2.编译源代码
      首先执行 cov01 -s 查看是否已经启用工具,如果未启用,执行cov01 -1 启用工具
      然后按照正常的步骤编译,此时唯一的变化是编译时,实际上使用的是BullseyeCoverage 自带的编译器。
      编译完成后,会生成test.cov 文件。
      最后执行cov01 -0 停用工具

注意,如果被评估的程序是长期运行的Deamon 进程,在编译之前你需要在源代码中增加以下代码:

  1. #if _BullseyeCoverage 
  2.     cov_write(); 
  3. #endif

      BullseyeCoverage 工具是在程序执行退出后,向覆盖率文件中写入收集到的数据,对于Deamon进程,数据就会一直在内存中,不会写入覆盖率文件中。
      以上代码只有在cov01 启用BullseyeCoverage 时才会生效,如果上面的代码生效,会在程序执行到这段代码时,将数据写入到覆盖率文件中。
      至于上面的代码写在源代码的哪一行,我认为是加在你执行测试时,运行的最后一行代码的后面即可。

3.执行程序
      将第二步编译好的程序进行部署,test.cov 文件拷贝至可执行程序目录下,执行完测试之后,test.cov 文件中会写入本次测试的覆盖率统计数据。

4.覆盖率分析
在命令行界面下,使用以下命令可以查看相应的覆盖率信息:
(1)covsrc -f test.cov  [ filename | dir ]
        查看源代码总体覆盖率情况;
(2)covfn -f test.cov  [ filename | dir ]
        查看函数覆盖率;
(3)covclass -f test.cov [ filename | dir ] 

        查看类覆盖率;

(4)可以使用CoverageBrowser test.cov 进行界面化查看,需要使用备注方式安装。

        
      另外还可以使用 covhtml 将test.cov 文件中的数据转换成html格式,就可以在浏览器中打开。
covhtml -f test.cov html_dir

      这里可能会报错,找不到源代码,因为工具会结合源代码来展示覆盖率的结果,如果找不到源代码也能生成覆盖率数据,但不能进入到相应的代码中查看。
      官网上介绍了两种方法解决这个问题,通过covhtml的-d 选项来指定源代码的目录,或者通过 COVSRCDIR 环境变量来指定,
      可能由于版本的原因,以上方法在我使用的过程中都未奏效,那只有把test.cov文件拷贝回原来的生成路径,就OK了。

      用浏览器打开html_dir目录下的 index.html 就可以看到 Function Coverage、Condition/decision Coverage 覆盖和未覆盖的数目及比例。
      还要提一个可能产生困惑的地方,就是在浏览器中,打开某个源代码文件时,最右端会有一些 -->、 T、F、t、f、X 等等这样的标记,
      它们表示代码执行的一些轨迹,以及代码的具体覆盖情况,具体的含义可以参考官网给出的解释。


An arrow --> indicates incomplete coverage.
An X indicates one of:
    a function or lambda expression that was entered
    a switch label that was selected
    a try-block that finished
    an exception handler that was entered
    a range-based for statement body that was entered
A T or F indicates a boolean decision that evaluated true or false, respectively.
A t or f indicates a boolean condition within a decision if the condition evaluated true or false, respectively.
A k indicates a constant decision or condition. Since no variation in coverage is possible, this mark is supplementary.

The slash / means this probe is excluded from summary results.

 

备注:

一、搭建Bullseye环境

1.      获取BullseyeCoverage源码(BullseyeCoverage-8.13.21-Linux-x86)

2.      运行echo $PATH >install-path

3.      sudo ./install --prefix ~/XXX/BullseyeCoverage/bullseye_install/--key 安装秘钥

bullseye_install —— 事先创建的文件夹

安装秘钥不公开,需要时,从xxx处获取

4.      将Busseye的目录添加至PATH中

exportPATH=/XXX/BullseyeCoverage/bullseye_install/bin:$PATH

5.      设置Busseye的输出文件

export COVFILE=/XXX/BullseyeCoverage/CoverageFile/test.cov

6.      开启Bullseye

cov01 -1

 

linux下的安装说明(参考安装目录下的readme文件):
1、注册:./extract -key <注册码>
2、安装 echo $PATH >install_path;./install --prefix=<directory>
3、设置环境变量:在.bash_profile的PATH中加入ccover/bin的路径,增加环境变量export COVFILE=`pwd`/test.cov(退出全部ssh后重新登陆,使PATH生效,否则会报安装错误)
4、打开c-cover编译开关:cov01 -1
5、重新编译应用程序,并执行即可,无需对makefile文件做任何修改

对程序进行一系列的测试后,就可以用covsrc、covfn、covdir、covbr、covclass等命令查看覆盖率,另外还有工具covmerge、covc、covselect等工具可以使用。
其中:
covsrc:查看源文件的覆盖情况
covfn:查看某个函数的覆盖情况
covbr:查看覆盖细节


各种符号说明:
-->       没有被执行到的函数、条件判断、switch、while/for、catch等
X         某个函数已被执行,并支持classs内的函数
T/t       某处条件判断为真
F/f       某处条件判断为假
TF/tf     某处条件判断时,真假值都成立过
K         某处条件为常量
covdir:查看文件夹的覆盖情况
covclass:查看类的覆盖情况

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐