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()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM