IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]展示C代码覆盖率的gcovr工具简介及相关命令使用示例

    zhouzxi发表于 2015-12-18 17:09:16
    love 0

    (本人正在参加2015博客之星评选,诚邀你来投票,谢谢:http://vote.blog.csdn.net/blogstar2015/candidate?username=zhouzxi)

    最近,因为要展示某项目的单元测试的代码覆盖率,我无意间在网上找到了gcovr工具。使用之后,觉得这个工具相当的不错,于是便写下这篇文章,可供相关的开发人员参考。

    简而言之,gcovr是一个将单元测试中的代码覆盖率以多种方式(包括列表方式、XML文件方式、HTML网页方式等)展示出来的工具,目前最新的版本是3.2。gcovr的下载地址是:https://pypi.python.org/pypi/gcovr/。

    该工具运行在Linux之下,解压后,将scripts目录下的gcovr拷贝到/usr/bin目录下就可以了。

    下面以寻找栈的增长方向的FindStackDirection.c程序为例,介绍gcovr的使用方法。

    程序源代码为:

    /**********************************************************************
    * 版权所有 (C)2015, Zhou Zhaoxiong。
    *
    * 文件名称:FindStackDirection.c
    * 文件标识:无
    * 内容摘要:寻找栈的增长方向
    * 其它说明:无
    * 当前版本:V1.0
    * 作    者:Zhou Zhaoxiong
    * 完成日期:20151218
    *
    **********************************************************************/
    #include <stdio.h>
    
    // 重定义数据类型
    typedef unsigned char  UINT8;
    typedef signed   int   INT32;
    
    // 函数声明
    void FindStackDirection(void);
    
    
    /**********************************************************************
    * 功能描述:主函数
    * 输入参数:无
    * 输出参数:无
    * 返 回 值:无
    * 其它说明:无
    * 修改日期        版本号      修改人              修改内容
    * ---------------------------------------------------------------
    * 20151218        V1.0     Zhou Zhaoxiong          创建
    ***********************************************************************/
    INT32 main()
    {
        FindStackDirection();
    
        return 0; 
    }
    
    
    /**********************************************************************
    * 功能描述:查找栈增长方向
    * 输入参数:无
    * 输出参数:无
    * 返 回 值:无
    * 其它说明:无
    * 修改日期        版本号      修改人              修改内容
    * ---------------------------------------------------------------
    * 20151218        V1.0     Zhou Zhaoxiong          创建
    ***********************************************************************/
    void FindStackDirection(void)
    {
        UINT8  iStackAddr        = 0;        // 用于获取栈地址
        static UINT8 *pStackAddr = NULL;     // 用于存放第一个iStackAddr的地址 
    
        if (pStackAddr == NULL)              // 第一次进入
        {                          
            pStackAddr = &iStackAddr;        // 保存iStackAddr的地址
            FindStackDirection();            // 递归 
        }
        else                                 // 第二次进入 
        {  
            if (&iStackAddr > pStackAddr)        // 第二次iStackDirection的地址大于第一次iStackDirection, 那么说明栈增长方向是向上的
            {   
                printf("Stack grows up!\n");
            }
            else if (&iStackAddr < pStackAddr)   // 第二次iStackDirection的地址小于第一次iStackDirection, 那么说明栈增长方向是向下的
            {  
                printf("Stack grows down!\n");
            }
            else
            {
                printf("Bad stack!\n");
            }
        }
    } 
    
    

    1.程序编译及执行
    将示例程序上传到Linux机器上,并在程序所在的目录下使用“gcc -fprofile-arcs -ftest-coverage -fPIC -O0 FindStackDirection.c -o FindStackDirection”命令对程序进行编译,生成FindStackDirection.gcno和FindStackDirection文件。

    编译命令中的“-fprofile-arcs -ftest-coverage -fPIC”用于产生能够被gcovr命令处理的文件。

    接着执行“./FindStackDirection”命令,又生成了FindStackDirection.gcda文件。

    2.输出列表形式的代码覆盖率
    在程序所在的目录下运行“gcovr -r .”命令,可看到输出结果如下:

    ------------------------------------------------------------------------------
                      GCC Code Coverage Report
    Directory: .
    ------------------------------------------------------------------------------
    File                   Lines    Exec  Cover   Missing
    ------------------------------------------------------------------------------
    FindStackDirection.c      14      12    85%   65,73
    ------------------------------------------------------------------------------
    TOTAL                     14      12    85%
    ------------------------------------------------------------------------------
    

    这就是代码覆盖率报告,我们可以看到,程序运行之后,覆盖了85%的代码。

    3.输出分支覆盖率
    在程序所在的目录下运行“gcovr -r . –branches”命令,可看到输出结果如下:

    ------------------------------------------------------------------------------
                     GCC Code Coverage Report
    Directory: .
    ------------------------------------------------------------------------------
    File                   Branches   Taken  Cover   Missing
    ------------------------------------------------------------------------------
    FindStackDirection.c        6        4    66%   63,67
    ------------------------------------------------------------------------------
    TOTAL                       6        4    66%
    ------------------------------------------------------------------------------
    

    我们可以看到,程序一共有6个分支,执行了其中的4个。

    4.输出展示覆盖率的XML文件
    在程序所在的目录下运行“gcovr -r . –xml-pretty”命令,可看到输出结果如下:

    <?xml version="1.0" ?>
    <!DOCTYPE coverage
      SYSTEM 'http://cobertura.sourceforge.net/xml/coverage-03.dtd'>
    <coverage branch-rate="0.666666666667" line-rate="0.857142857143"
     timestamp="1450424892" version="gcovr 3.2">
     <sources>
      <source>
       .
      </source>
     </sources>
     <packages>
      <package branch-rate="0.666666666667" complexity="0.0"
       line-rate="0.857142857143" name="">
       <classes>
        <class branch-rate="0.666666666667" complexity="0.0"
         filename="FindStackDirection.c" line-rate="0.857142857143"
         name="FindStackDirection_c">
         <methods/>
         <lines>
          <line branch="false" hits="0" number="65"/>
          <line branch="false" hits="1" number="34"/>
          <line branch="false" hits="1" number="35"/>
          <line branch="false" hits="1" number="37"/>
          <line branch="false" hits="0" number="73"/>
          <line branch="false" hits="2" number="76"/>
          <line branch="true" condition-coverage="50% (1/2)" hits="1" number="63">
           <conditions>
            <condition coverage="50%" number="0" type="jump"/>
           </conditions>
          </line>
          <line branch="true" condition-coverage="50% (1/2)" hits="1" number="67">
           <conditions>
            <condition coverage="50%" number="0" type="jump"/>
           </conditions>
          </line>
          <line branch="false" hits="2" number="52"/>
          <line branch="false" hits="2" number="53"/>
          <line branch="true" condition-coverage="100% (2/2)" hits="2"
           number="56">
           <conditions>
            <condition coverage="100%" number="0" type="jump"/>
           </conditions>
          </line>
          <line branch="false" hits="1" number="58"/>
          <line branch="false" hits="1" number="59"/>
          <line branch="false" hits="1" number="69"/>
         </lines>
        </class>
       </classes>
      </package>
     </packages>
    </coverage>
    

    我们可以看到,命令的执行结果是输出了XML格式的代码覆盖率报告。

    5.输出展示覆盖率的HTML文件
    在程序所在的目录下运行“gcovr -r . –html -o FindStackDirection.html”命令,可看到在当前目录下生成了FindStackDirection.html文件。用浏览器打开,其内容如下图所示:
    这里写图片描述

    这个HTML文件以图形化的方式直观地展示了代码的覆盖率。

    我们还可以添加“–html-details”选项为代码工程中的每个文件生成一个独立的web页。例如,我们在程序所在的目录下运行“gcovr -r . –html –html-details -o FindStackDirection2.html”命令,可看到在当前目录下生成了FindStackDirection2.html文件和FindStackDirection2.FindStackDirection.c.html文件。用浏览器打开FindStackDirection2.html文件,其内容如下图所示:
    这里写图片描述

    可以看到,页面上的“FindStackDirection.c”文字有一条下划线,单击该文字,出现的一个新的页面,其内容如下图所示:
    这里写图片描述

    可以看到,某些代码行前面有数字,表示该行运行的次数。如“if (pStackAddr == NULL)”行运行了2次,“pStackAddr = &iStackAddr;”行运行了1次。

    6.更多的gcovr命令
    前面展示了部分经常用到的gcovr命令,更详细的gcovr命令及对命令的介绍请参考此文档:http://gcovr.com/guide.pdf。

    7.总结
    如果大家要查看自己所编写的C代码在执行过程中的代码覆盖率,那么gcovr工具就是一个相当不错的选择。

    下面是两个网址,大家可以通过它们对gcovr有一个更加深入的了解:

    (1) gcovr官网:http://gcovr.com/

    (2) 如何利用gcovr生成代码覆盖率的趋势图:http://www.cnblogs.com/jackyim/p/3772306.html

    最后再啰嗦几句,gcovr是一个用Python编写的开源软件,大小只有几十KB,但功能强大。让我们一起向开发该软件的前辈们致敬!



沪ICP备19023445号-2号
友情链接