#!/bin/bash # ================================================================================================ # Audio Backend - 测试覆盖率报告生成脚本 # ================================================================================================ # 描述: 生成项目的代码覆盖率报告,基于gcov和lcov # ================================================================================================ # 设置颜色输出 GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[0;33m' BLUE='\033[0;34m' NC='\033[0m' # 无颜色 # 脚本所在的目录路径 SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" # 项目根目录 ROOT_DIR="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" # 构建目录 BUILD_DIR="$ROOT_DIR/build" # 测试结果目录 TEST_RESULTS_DIR="$ROOT_DIR/test-results" # 覆盖率报告目录 COVERAGE_DIR="$TEST_RESULTS_DIR/coverage" # 打印脚本信息 echo -e "${BLUE}=========================================================${NC}" echo -e "${BLUE} 音频后端测试覆盖率报告生成脚本 ${NC}" echo -e "${BLUE}=========================================================${NC}" echo -e "${YELLOW}项目根目: ${ROOT_DIR}${NC}" echo -e "${YELLOW}覆盖率报目录: ${COVERAGE_DIR}${NC}" echo "" # 确保覆盖率报告目录存在 mkdir -p "$COVERAGE_DIR" # 检查lcov是否安装 if ! command -v lcov &> /dev/null; then echo -e "${RED}错误: lcov 未安装。请安装 lcov 工具后重试。${NC}" echo -e "可以使用以下命安装: sudo apt-get install lcov (Ubuntu/Debian)" exit 1 fi # 检查gcov是否安装 if ! command -v gcov &> /dev/null; then echo -e "${RED}错误: gcov 未安装。请安装 gcov 工具后重试。${NC}" echo -e "gcov 通常随 gcc 一起安装: sudo apt-get install gcc (Ubuntu/Debian)" exit 1 fi # 检查构建目录是否存在 if [ ! -d "$BUILD_DIR" ]; then echo -e "${RED}错误: 构建目录不存在。请确保项目已经以覆盖率模式构建。${NC}" echo -e "可以使用以下命构建项目: cmake -DENABLE_COVERAGE=ON .. && make" exit 1 fi echo -e "${BLUE}开始生成覆盖率报告...${NC}" # 重置覆盖率计数器 echo -e "重置覆盖率计数..." lcov --zerocounters --directory "$BUILD_DIR" lcov --capture --initial --directory "$BUILD_DIR" --output-file "$COVERAGE_DIR/base.info" # 运行单元测试以生成覆盖率数据 echo -e "运行单元测试以成覆盖率数据..." "$SCRIPT_DIR/run_unit_tests.sh" > /dev/null 2>&1 test_result=$? if [ $test_result -ne 0 ]; then echo -e "${YELLOW}警告: 单元测试运行失败。覆盖率数据可能不完整。${NC}" fi # 收集覆盖率数据 echo -e "收集覆盖率数据..." lcov --capture --directory "$BUILD_DIR" --output-file "$COVERAGE_DIR/test.info" lcov --add-tracefile "$COVERAGE_DIR/base.info" --add-tracefile "$COVERAGE_DIR/test.info" \ --output-file "$COVERAGE_DIR/total.info" # 过滤掉第三方库和测试代码 echo -e "过滤覆盖率数据..." lcov --remove "$COVERAGE_DIR/total.info" \ "/usr/include/*" \ "/usr/local/include/*" \ "*/third_party/*" \ "*/tests/*" \ "*/googletest/*" \ --output-file "$COVERAGE_DIR/filtered.info" # 生成HTML报告 echo -e "生成HTML覆盖率报告..." genhtml --output-directory "$COVERAGE_DIR/html" \ --title "音频后端代码覆率报告" \ --legend --demangle-cpp \ "$COVERAGE_DIR/filtered.info" if [ $? -ne 0 ]; then echo -e "${RED}错误: 无法生成HTML覆盖报告。${NC}" exit 1 fi # 生成覆盖率摘要 echo -e "生成覆盖率摘要..." lcov --summary "$COVERAGE_DIR/filtered.info" > "$COVERAGE_DIR/summary.txt" 2>&1 # 提取覆盖率数据 LINES_PERCENT=$(grep -oP 'lines\.*: \K[0-9.]+%' "$COVERAGE_DIR/summary.txt" | sed 's/%//') FUNCTIONS_PERCENT=$(grep -oP 'functions\.*: \K[0-9.]+%' "$COVERAGE_DIR/summary.txt" | sed 's/%//') BRANCHES_PERCENT=$(grep -oP 'branches\.*: \K[0-9.]+%' "$COVERAGE_DIR/summary.txt" | sed 's/%//') # 检查覆盖率目标 LINES_TARGET=80.0 FUNCTIONS_TARGET=80.0 BRANCHES_TARGET=70.0 LINES_RESULT="${GREEN}过${NC}" FUNCTIONS_RESULT="${GREEN}通过${NC}" BRANCHES_RESULT="${GREEN}通过${NC}" if (( $(echo "$LINES_PERCENT < $LINES_TARGET" | bc -l) )); then LINES_RESULT="${RED}未达标${NC}" fi if (( $(echo "$FUNCTIONS_PERCENT < $FUNCTIONS_TARGET" | bc -l) )); then FUNCTIONS_RESULT="${RED}未达标${NC}" fi if (( $(echo "$BRANCHES_PERCENT < $BRANCHES_TARGET" | bc -l) )); then BRANCHES_RESULT="${RED}未达标${NC}" fi # 打印覆盖率结果 echo -e "${BLUE}=========================================================${NC}" echo -e "${BLUE} 覆盖率报告汇总 ${NC}" echo -e "${BLUE}=========================================================${NC}" echo -e "行覆盖率: ${LINES_PERCENT}% (目标: ${LINES_TARGET}%) - ${LINES_RESULT}" echo -e "函数覆盖率: ${FUNCTIONS_PERCENT}% (目标: ${FUNCTIONS_TARGET}%) - ${FUNCTIONS_RESULT}" echo -e "分支覆盖率: ${BRANCHES_PERCENT}% (目标: ${BRANCHES_TARGET}%) - ${BRANCHES_RESULT}" echo "" echo -e "详细HTML报告已生成到: ${YELLOW}${COVERAGE_DIR}/html/index.html${NC}" echo "" # 生成简单的覆盖率图标 BADGE_DIR="$COVERAGE_DIR/badges" mkdir -p "$BADGE_DIR" # 生成SVG覆盖率徽章 generate_badge() { local title=$1 local percent=$2 local filename=$3 local color="red" if (( $(echo "$percent >= 90.0" | bc -l) )); then color="brightgreen" elif (( $(echo "$percent >= 80.0" | bc -l) )); then color="green" elif (( $(echo "$percent >= 70.0" | bc -l) )); then color="yellowgreen" elif (( $(echo "$percent >= 60.0" | bc -l) )); then color="yellow" elif (( $(echo "$percent >= 50.0" | bc -l) )); then color="orange" fi cat > "$BADGE_DIR/$filename" << EOF $title $percent% EOF } generate_badge "行覆盖率" "$LINES_PERCENT" "line-coverage.svg" generate_badge "函数覆盖率" "$FUNCTIONS_PERCENT" "function-coverage.svg" generate_badge "分支覆盖率" "$BRANCHES_PERCENT" "branch-coverage.svg" echo -e "覆盖率徽章已生到: ${YELLOW}${BADGE_DIR}${NC}" echo "" # 检查是否满足覆盖率要求 if (( $(echo "$LINES_PERCENT >= $LINES_TARGET" | bc -l) )) && (( $(echo "$FUNCTIONS_PERCENT >= $FUNCTIONS_TARGET" | bc -l) )) && (( $(echo "$BRANCHES_PERCENT >= $BRANCHES_TARGET" | bc -l) )); then echo -e "${GREEN}覆盖率目达成!${NC}" exit 0 else echo -e "${YELLOW}覆盖率未目标!${NC}" exit 0 # 不将覆盖率不足视为错误,但会发出警告 fi