• CMake编译项目集成gcov/lcov代码覆盖率测试


    转自https://blog.csdn.net/lostaway/article/details/40948841,并针对自己项目做了小幅修改,在此感谢原作者

    完整演示项目Github地址:https://github.com/lostaway/EasonCodeShare/tree/master/CMakeGcovSupport

    初始项目目录结构:

    CMakeGcovSupport
    ├── CMakeLists.txt
    ├── bin
    ├── build
    ├── include
    │   └── name.h
    ├── libgreeting
    │   ├── CMakeLists.txt
    │   ├── include
    │   │   └── greeting.h
    │   └── src
    │       ├── CMakeLists.txt
    │       ├── greeting.cpp
    │       └── yelp.cpp
    └── src
        ├── CMakeGcovSupport.cpp
        ├── CMakeLists.txt
        └── name.cpp

    示例程序是个很简单的输出一行问候语的程序。为了演示复杂目录结构下CMake集成Gcov/lcov的方法,故意将输出问候语的函数单独放到了 libgreeting 静态库中。执行如下编译命令:

    $ cd CMakeGcovSupport
    $ mkdir build
    $ cd build
    $ cmake -DENABLE_COVERAGE=ON ..
    $ gmake all

    执行 CMake 外部编译之后,CMake 在 build 目录内为我们生成了 .gcno 文件:

    CMakeGcovSupport
    ├── CMakeLists.txt
    ├── bin
    │   └── CMakeGcovSupport
    ├── build
    │   ├── ......
    │   ├── libgreeting
    │   │   ├── ......
    │   │   └── src
    │   │       ├── CMakeFiles
    │   │       │   ├── ......
    │   │       │   ├── greeting.dir
    │   │       │   │   ├── ......
    │   │       │   │   ├── greeting.cpp.gcno
    │   │       │   │   ├── greeting.cpp.o
    │   │       │   │   ├── ......
    │   │       │   │   ├── yelp.cpp.gcno
    │   │       │   │   └── yelp.cpp.o
    │   │       │   └── ......
    │   │       └── ......
    │   └── src
    │       ├── CMakeFiles
    │       │   ├── ......
    │       │   ├── CMakeGcovSupport.dir
    │       │   │   ├── CMakeGcovSupport.cpp.gcno
    │       │   │   ├── CMakeGcovSupport.cpp.o
    │       │   │   ├── ......
    │       │   │   ├── name.cpp.gcno
    │       │   │   ├── name.cpp.o
    │       │   │   └── ......
    │       │   └── progress.marks
    │       └── ......
    ├── include
    ├── libgreeting
    └── src

    为了避免接下来执行程序过程中,未覆盖的源码文件的覆盖率信息丢失,我们需要对覆盖率信息进行初始化操作:

    $ cd CMakeGcovSupport
    $ lcov -d build -z
    $ lcov -d build -b . --no-external --initial -c -o CMakeGcovSupportInitialCoverage.info

    然后我们执行 bin 中的 CMakeGcovSupport, main() 函数中将会调用 Greeting() 和 Name()  函数,而不会调用到 Yelp() 函数。

    $ cd CMakeGcovSupport
    $ cd bin
    $ ./CMakeGcovSupport
    $ Hello, gcov.

    此时我们会看到在 .gcno 所在目录,有同名的 .gcda 覆盖率数据文件生成了。执行以下命令,生成覆盖率测试报告:

    $ cd CMakeGcovSupport
    $ lcov -d build -b . --no-external -c -o CMakeGcovSupportCoverage.info
    $ genhtml -o CMakeGcovSupportCoverageReport --prefix='pwd' CMakeGcovSupportInitialCoverage.info CMakeGcovSupportCoverage.info

    用浏览器打开 CMakeGcovSupportCoverageReport 目录中的 index.html 查看覆盖率报告。

    以下部分为具体实施时可能会遇到的问题:

    1.报告中不包含branch覆盖率信息

       原因在于lcov 1.10以后版本默认不包含branch coverage信息,需要通过修改 vim /etc/lcovrc 文件默认打开branch分支信息的输出,具体修改如下:

       # Specify if branch coverage data should be collected andprocessed.

       lcov_branch_coverage = 1       #去掉注释,值改为1

       # Include branch coverage datadisplay (can be disabled by the --no-branch-coverage option of genhtml)

       genhtml_branch_coverage = 1      #去掉注释,值改为1

       ---------------------------------------------------------------

       或者在lcov命令后加上参数 lcov -d <gcda目录位置> -b <测试代码路径> -c -o result.info --rc lcov_branch_coverage=1

       再在genhtml命令后加上参数 genhtml -o result result.info --branch-coverage

    2.对于复杂项目,不想包含某个文件夹内的文件覆盖率信息,即反向去除不需要的文件,可以使用 --remove 参数

       lcov --remove all.info '*/lib/*' -o result.info

       正向提取需要的文件,可以使用 --extract 参数

       lcov --extract all.info '*/src/*' -o result.info

       注意:lcov 不允许同时使用--extract  和  --remove

    3.使用 --no-external 参数排除外部库

    也可以将命令写成脚本文件:

    # InitialCoverage.sh 此脚本文件在编译动作完成后运行,需使用chmod +x InitialCoverage.sh将其转变为可执行文件

    $!/bin/sh

    echo "Start initialize lcov coverage"

    lcov -d cmake-build-release/src -z

    lcov -d cmake-build-release/src -b . --no-external --initial -c -o InitialCoverage.info

    lcov --remove InitialCoverage.info '*/lib/*' -o InitCoverage.info

    rm -rf InitialCoverage.info

    exit 1

    # ReportCoverage.sh 此脚本文件在runtest或gtest后运行

    #!/bin/sh

    echo "Start report lcov coverage"

    lcov -d cmake-build-release/src -b . --no-external -c -o ReportCoverage.info

    lcov --remove ReportCoverage.info '*/lib/*' -o ResultCoverage.info

    genhtml -o CoverageReport --prefix='pwd' InitCoverage.info ResultCoverage.info

    rm -rf InitCoverage.info

    rm -rf ReportCoverage.info

    rm -rf ResultCoverage.info

    exit 1 

    另外,CMakeLists.txt中需要添加以下几行:

    set(ENABLE_COVERAGE TRUE)

    if(ENABLE_COVERAGE)

        message(STATUS "Use gcov for code coverage test")

        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")

    endif()

  • 相关阅读:
    Qt中的 Size Hints 和 Size Policies
    __declspec,__cdecl,__stdcall区别和作用
    深入理解DLL文件
    TCP/IP TIME_WAIT状态原理
    Linux 网络编程 高级套接字
    OpenCV 图像处理学习笔记(一)
    C++运算符重载的规则
    WinSock异步IO模型之Select
    ASSER、VERIFY、TRACE详解
    VC++ 网络编程总结(二)
  • 原文地址:https://www.cnblogs.com/chwei2ch/p/10678467.html
Copyright © 2020-2023  润新知