如何使用gcov/lcov生成C++全代码库的单元测试覆盖率报告
解决方案
要统计包含未覆盖文件在内的全代码库覆盖率,你需要补充「零覆盖率基线生成」和「覆盖率数据合并」两个步骤,具体操作如下:
步骤1:调整全代码库编译配置
首先确保整个代码库的所有C/C++源文件在编译时都开启了覆盖率编译选项:
- 编译参数添加
--coverage(等价于-fprofile-arcs -ftest-coverage) - 链接参数添加
--coverage(等价于-lgcov)
即使某个源文件没有对应的单元测试,也要保证它编译时生成了对应的.gcno文件,这是统计它零覆盖率的基础。
步骤2:调整覆盖率生成脚本
原来的脚本只捕获了测试运行后的覆盖率数据,需要补充初始基线捕获、合并逻辑,修改后的脚本如下:
# Get the path to the current folder SCRIPT_DIR=$(pwd) # SRC_DIR 是编译产物目录,包含所有.gcno文件 SRC_DIR="$SCRIPT_DIR/../../build-KEBPLCComService-Desktop-Debug/" # CODE_BASE_DIR 是你的源代码根目录,用来过滤只统计自己的代码 CODE_BASE_DIR="$SCRIPT_DIR/../../src/" # COV_DIR 是覆盖率结果存储目录 COV_DIR="$SCRIPT_DIR/../coverage" ############################################################################################################ # Path where the HTML files should be saved HTML_RESULTS="${COV_DIR}/html" # Create the html folder if it does not exists mkdir -p ${HTML_RESULTS} # ------------------- 新增部分开始 ------------------- # 1. 生成零覆盖率基线:捕获所有编译生成的.gcno文件的初始0覆盖率数据 lcov -c -i -d "${SRC_DIR}" -o "${COV_DIR}/coverage-base.info" # 2. 这里补充运行你的所有单元测试的步骤,运行完测试才会生成.gcda数据 # 示例:./run_all_gtest_binaries # ------------------- 新增部分结束 ------------------- # 3. 捕获测试运行后的覆盖率数据 lcov -d "${SRC_DIR}" -c -o "${COV_DIR}/coverage-test.info" # 4. 合并基线数据和测试运行数据,得到包含全代码库的覆盖率数据 lcov -a "${COV_DIR}/coverage-base.info" -a "${COV_DIR}/coverage-test.info" -o "${COV_DIR}/coverage-all.info" # 过滤不需要统计的路径,这里调整你原来的过滤规则,注意不要误过滤自己的源码路径 # 建议先用-e提取你要统计的源码路径,再过滤不需要的内容,更精准 lcov -e "${COV_DIR}/coverage-all.info" "${CODE_BASE_DIR}*" -o "${COV_DIR}/coverage-src-only.info" lcov -r "${COV_DIR}/coverage-src-only.info" "*Qt*.framework*" "*/tests/*" "*Xcode.app*" "*.moc" "*moc_*.cpp" "*/test/*" -o "${COV_DIR}/coverage-filtered.info" # Generate the HTML files genhtml -o "${HTML_RESULTS}" "${COV_DIR}/coverage-filtered.info" # Reset our counts lcov -d "${SRC_DIR}" -z # Open the index.html firefox "${HTML_RESULTS}/index.html"
关键说明
-i参数是lcov的初始捕获模式,只会读取.gcno文件生成全零的覆盖率基线,不会依赖运行后的.gcda文件- 合并后的数据会自动把没有被测试执行到的源文件统计为0覆盖率,最终得到的就是全代码库的覆盖率指标
- 你原来的过滤规则里的
*/build*/*会过滤掉编译目录下的有效数据,已经在修改后的脚本里移除,改为用-e主动提取源码根目录下的文件,避免误过滤
内容的提问来源于stack exchange,提问作者vishnu
相关产品推荐
相关产品推荐

