zoukankan      html  css  js  c++  java
  • GCOV&LCOV&GCOVR入门

    一、概述

    代码覆盖率(Code coverage)是衡量软件测试质量的一个重要指标。

    它描述了当一个特定的测试套件(test suite)运行时,程序源代码被执行的程度。例如,一些更具体的覆盖率指标有:

    1. Statement Coverage:描述源代码中有哪些代码行被执行,各自被执行了多少次
    2. Branch coverage:一般用于描述if语句/或其它条件语句的各分支的执行情况
    3. Function coverage:顾名思义,描述源代码中有哪些函数被执行了
    4. ······

    代码覆盖率测试工具可以帮助我们发现代码中未被测试的部分,

    而gcov则是一款和GCC配套发布的[经典]代码覆盖率分析工具(仅仅是对覆盖率信息文件进行分析)。

    同为代码覆盖率分析工具,GCOV&LCOV&GCOVR之间的差异:

    • GCOV:与GCC配套,不需要安装,生成纯文本文件
    • LCOV:需要安装,跨平台麻烦,生成HTML页面
    • GCOVR:需要安装,跨平台容易,且指令比LCOV少,生成HTML页面

    PS. 不仅仅是C或者C++,GCC所支持的语言它们应该都是支持的,例如说Fortran 

    二、关于gcov的安装

    gcov是随gcc一起发布的,并不需要独立安装,设法装上gcc就OK了。对于WINDOWS系统,通过MinGW安装gcc相关的组件即可使用gcov。而对于Linux系统而言,通常会默认安装gcc,因此一般不需要自己安装。

    三、代码覆盖率测试(以GCOV为例)

    首先,我们需要通过gcc的编译选项获取覆盖率信息文件(例如每行代码被执行了多少次啊),

    这里的“生成覆盖率信息”的步骤对任何一个覆盖率分析工具都是完全一样的,

    然后,用gcov收集、分析覆盖率信息文件并生成代码覆盖率报告。

    用于演示的C程序源代码(包含一个计算阶乘的函数):

    #include <stdio.h>
    
    int factorial(int n);
    
    int main()
    {
        int result0 = factorial(0);
        int result1 = factorial(1);
        int result2 = factorial(10);
        
        if (result0 != 1) printf("test0 failed, actual=%d.
    ", result0);
        if (result1 != 1) printf("test1 failed, actual=%d.
    ", result1);
        if (result2 != 3628800) printf("test2 failed, actual=%d.
    ", result2);
        
        return 0;
    }
    
    int factorial(int n)
    {
        if (n < 0) {
            printf("Factorial is defined only for non-negative integer numbers.");
            return -1;
        }
            
        if (n > 1) {
            return n * factorial(n - 1);
        } else {
            return 1;
        }
    }
    factorial.c

    1、编译源代码

    要生成覆盖率信息文件,必须添加以下编译选项:

    gcc -fprofile-arcs -ftest-coverage factorial.c

    将factorial.c编译之后,我们将得到一个被“改造”过的可执行程序a.exe,该程序中包含了一些额外的指令,用于记录程序中每一行被执行的次数。以及一个后缀为.gcno的factorial.gcno文件,它是即将被gcov引用的关键数据文件。

    编译选项说明:

    • -ftest-coverage选项:添加记录单行代码执行次数的指令
    • -fprofile-arc选项:添加程序每个分支的检测代码(if或者其它条件语句)

    2、运行可执行程序

    ./a.exe

    运行可执行程序之后,我们会得到一个factorial.gcda的文件,它和factorial.gcno一样是即将被gcov引用的数据文件(代码覆盖率信息文件)。

    3、通过gcov命令生成代码覆盖率报告

    gcov factorial.c
    File 'factorial.c'
    Lines executed:86.67% of 15
    Creating 'factorial.c.gcov'

    执行指令后,gcov会引用之前的数据文件生成一个代码覆盖率报告factorial.c.gcov

    $ cat factorial.c.gcov
            -:    0:Source:factorial.c
            -:    0:Graph:factorial.gcno
            -:    0:Data:factorial.gcda
            -:    0:Runs:1
            -:    0:Programs:1
            -:    1:#include <stdio.h>
            -:    2:
            -:    3:int factorial(int n);
            -:    4:
            1:    5:int main()
            -:    6:{
            1:    7:        int result0 = factorial(0);
            1:    8:        int result1 = factorial(1);
            1:    9:    int result2 = factorial(10);
            -:   10:
            1:   11:        if (result0 != 1) printf("test0 failed, actual=%d.
    ", result0);
            1:   12:        if (result1 != 1) printf("test1 failed, actual=%d.
    ", result1);
            1:   13:        if (result2 != 3628800) printf("test2 failed, actual=%d.
    ", result2);
            -:   14:
            1:   15:    return 0;
            -:   16:}
            -:   17:
           12:   18:int factorial(int n)
            -:   19:{
           12:   20:        if (n < 0) {
        #####:   21:                printf("Factorial is defined only for non-negative integer numbers.");
        #####:   22:                return -1;
            -:   23:        }
            -:   24:
           12:   25:    if (n > 1) {
            9:   26:                return n * factorial(n - 1);
            -:   27:        } else {
            3:   28:                return 1;
            -:   29:        }
            -:   30:}

    “#####”所标记的是未被执行的语句。

    四、生成更全面、直观的代码覆盖率报告

    直接用gcov生成的代码覆盖率报告并不是很直观,因此一般应该都是用以下两款。

    1、LCOV

    Lcov是gcov的图形化前端,它和GCOV做的工作是差不多的,只不过最后输出的是HTML页面形式的代码覆盖率报告。

    Ubuntu系统下安装LCOV:

    sudo apt-get install lcov

    依然用之前的factorial.c演示。首先,按之前的步骤生成相关数据文件,例如xxx.gcda、xxx.gcno(PS. 不需要用gcov生成xxx.c.gcov文件)。然后,用LCOV收集相关数据并生成一个.info文件(方便起见直接在当前目录执行该命令):

    lcov --capture --directory . --output-file coverage.info

    最后,通过genhtml将coverage.info转化为HTML文件(genhtml是lcov自带的工具):

    genhtml coverage.info --output-directory out

    生成的OUT目录里包含了HTML版的代码覆盖率报告。

    在WINDOWS上安装LCOV比较繁琐,有人专门写了Windows上可运行的LCOV脚本[LCOV for Windows],但是我下载下来后没弄懂怎么用。

    2、GCOVR

    相比于LCOV,gcovr可能更方便一点。LCOV有的功能gcovr都有,并且gcovr也是开源的:https://github.com/gcovr/gcovr。它是用Python写的,这意味着只要有Python环境都可以使用gcovr,无论是WINDOWS还是LINUX。直接通过pip(Python的包管理工具)安装GCOVR:

    pip install gcovr

    还是和之前一样的步骤生成相关的代码覆盖率信息文件,然后直接用gcovr生成HTML代码覆盖率报告就行了:

    gcovr -r . --html --html-details -o coverage.html

     五、参考

  • 相关阅读:
    linux命令(8):du命令
    linux命令(7):ipcs/ipcrm命令
    linux命令(6):tar命令
    linux命令(5):netstat命令
    linux命令(4):vmstat命令
    linux命令(3):rpm命令
    linux命令(2):grep命令
    linux命令(1):sed命令
    链表中倒数第k个节点
    链表刷题总结
  • 原文地址:https://www.cnblogs.com/xkxf/p/10607500.html
Copyright © 2011-2022 走看看