@echo off REM ================================================================================================ REM Audio Backend - 测试覆盖率报告生成脚本 (Windows) REM ================================================================================================ REM 描述: 生成项目的代码覆盖率报告,基于OpenCppCoverage工具 REM ================================================================================================ setlocal EnableDelayedExpansion REM 设置颜色输出 set "GREEN=[92m" set "RED=[91m" set "YELLOW=[93m" set "BLUE=[94m" set "NC=[0m" REM 脚本所在的目录路径 set "SCRIPT_DIR=%~dp0" REM 项目根目录 for %%i in ("%SCRIPT_DIR%\..\..\..\") do set "ROOT_DIR=%%~fi" REM 构建目录 set "BUILD_DIR=%ROOT_DIR%\build" REM 测试结果目录 set "TEST_RESULTS_DIR=%ROOT_DIR%\test-results" REM 覆盖率报告目录 set "COVERAGE_DIR=%TEST_RESULTS_DIR%\coverage" REM 打印脚本信息 echo %BLUE%=========================================================%NC% echo %BLUE% 音频后端测试覆盖率报告生成脚本 %NC% echo %BLUE%=========================================================%NC% echo %YELLOW%项目根目录: %ROOT_DIR%%NC% echo %YELLOW%覆盖率报告目录: %COVERAGE_DIR%%NC% echo. REM 确保覆盖率报告目录存在 if not exist "%COVERAGE_DIR%" mkdir "%COVERAGE_DIR%" if not exist "%COVERAGE_DIR%\html" mkdir "%COVERAGE_DIR%\html" if not exist "%COVERAGE_DIR%\badges" mkdir "%COVERAGE_DIR%\badges" REM 检查OpenCppCoverage是否安装 where OpenCppCoverage.exe >nul 2>&1 if %ERRORLEVEL% neq 0 ( echo %RED%错误: OpenCppCoverage 未安装。请安装 OpenCppCoverage 工具后重试。%NC% echo 可以从以下网址下载: https://github.com/OpenCppCoverage/OpenCppCoverage/releases exit /b 1 ) REM 检查构建目录是否存在 if not exist "%BUILD_DIR%" ( echo %RED%错误: 构建目录不存在。请确保项目已经以覆盖率模式构建。%NC% echo 可以使用以下命令构建项目: cmake -DENABLE_COVERAGE=ON .. ^&^& cmake --build . exit /b 1 ) echo %BLUE%开始生成覆盖率报告...%NC% REM 收集单元测试可执行文件 set "UNIT_TEST_COUNT=0" set "UNIT_TESTS=" for /d %%d in ("%BUILD_DIR%\bin\tests\unit\*") do ( for %%f in ("%%d\*.exe") do ( if exist "%%f" ( set /a UNIT_TEST_COUNT+=1 set "UNIT_TESTS=!UNIT_TESTS! %%f" ) ) ) if %UNIT_TEST_COUNT% equ 0 ( echo %YELLOW%警告: 未找到单元测试可执行文件。%NC% exit /b 0 ) REM 创建覆盖率命令 set "COVERAGE_CMD=OpenCppCoverage.exe --export_type=html:%COVERAGE_DIR%\html --export_type=cobertura:%COVERAGE_DIR%\coverage.xml --sources=%ROOT_DIR%\src --excluded_sources=%ROOT_DIR%\tests --excluded_sources=third_party" REM 运行覆盖率分析 echo %BLUE%运行单元测试并收集覆盖率数据...%NC% %COVERAGE_CMD% --quiet %UNIT_TESTS% if %ERRORLEVEL% neq 0 ( echo %YELLOW%警告: 覆盖率分析运行失败。覆盖率数据可能不完整。%NC% ) REM 处理覆盖率XML报告以提取统计数据 echo %BLUE%提取覆盖率统计数据...%NC% REM 检查是否生成了XML报告 if not exist "%COVERAGE_DIR%\coverage.xml" ( echo %RED%错误: 无法找到覆盖率XML报告。%NC% exit /b 1 ) REM 使用PowerShell解析XML并提取覆盖率数据 powershell -Command "& { $xml = [xml](Get-Content '%COVERAGE_DIR%\coverage.xml') $coverage = $xml.coverage $linesValid = [int]$coverage.lines-valid $linesCovered = [int]$coverage.lines-covered $linesPercent = 0 if ($linesValid -gt 0) { $linesPercent = [math]::Round(($linesCovered / $linesValid) * 100, 2) } $branchesValid = [int]$coverage.branches-valid $branchesCovered = [int]$coverage.branches-covered $branchesPercent = 0 if ($branchesValid -gt 0) { $branchesPercent = [math]::Round(($branchesCovered / $branchesValid) * 100, 2) } # 计算函数覆盖率 (通过类的方法) $functionsValid = 0 $functionsCovered = 0 foreach($class in $coverage.packages.package.classes.class) { foreach($method in $class.methods.method) { $functionsValid++ if ([int]$method.line-rate -gt 0) { $functionsCovered++ } } } $functionsPercent = 0 if ($functionsValid -gt 0) { $functionsPercent = [math]::Round(($functionsCovered / $functionsValid) * 100, 2) } # 输出到文件 'LINES_PERCENT=' + $linesPercent | Out-File -FilePath '%COVERAGE_DIR%\lines_percent.txt' -Encoding ascii 'FUNCTIONS_PERCENT=' + $functionsPercent | Out-File -FilePath '%COVERAGE_DIR%\functions_percent.txt' -Encoding ascii 'BRANCHES_PERCENT=' + $branchesPercent | Out-File -FilePath '%COVERAGE_DIR%\branches_percent.txt' -Encoding ascii }" 2>nul REM 读取提取的覆盖率数据 if not exist "%COVERAGE_DIR%\lines_percent.txt" ( echo %RED%错误: 无法解析覆盖率数据。%NC% exit /b 1 ) for /f "tokens=1,* delims==" %%a in (%COVERAGE_DIR%\lines_percent.txt) do set LINES_PERCENT=%%b for /f "tokens=1,* delims==" %%a in (%COVERAGE_DIR%\functions_percent.txt) do set FUNCTIONS_PERCENT=%%b for /f "tokens=1,* delims==" %%a in (%COVERAGE_DIR%\branches_percent.txt) do set BRANCHES_PERCENT=%%b REM 检查覆盖率目标 set "LINES_TARGET=80.0" set "FUNCTIONS_TARGET=80.0" set "BRANCHES_TARGET=70.0" set "LINES_RESULT=%GREEN%通过%NC%" set "FUNCTIONS_RESULT=%GREEN%通过%NC%" set "BRANCHES_RESULT=%GREEN%通过%NC%" REM 比较覆盖率目标 powershell -Command "& { if ([double]'%LINES_PERCENT%' -lt [double]'%LINES_TARGET%') { Exit 1 } else { Exit 0 } }" if %ERRORLEVEL% neq 0 set "LINES_RESULT=%RED%未达标%NC%" powershell -Command "& { if ([double]'%FUNCTIONS_PERCENT%' -lt [double]'%FUNCTIONS_TARGET%') { Exit 1 } else { Exit 0 } }" if %ERRORLEVEL% neq 0 set "FUNCTIONS_RESULT=%RED%未达标%NC%" powershell -Command "& { if ([double]'%BRANCHES_PERCENT%' -lt [double]'%BRANCHES_TARGET%') { Exit 1 } else { Exit 0 } }" if %ERRORLEVEL% neq 0 set "BRANCHES_RESULT=%RED%未达标%NC%" REM 打印覆盖率结果 echo %BLUE%=========================================================%NC% echo %BLUE% 覆盖率报告汇总 %NC% echo %BLUE%=========================================================%NC% echo 行覆盖率: %LINES_PERCENT%%% (目标: %LINES_TARGET%%%) - %LINES_RESULT% echo 函数覆盖率: %FUNCTIONS_PERCENT%%% (目标: %FUNCTIONS_TARGET%%%) - %FUNCTIONS_RESULT% echo 分支覆盖率: %BRANCHES_PERCENT%%% (目标: %BRANCHES_TARGET%%%) - %BRANCHES_RESULT% echo. echo 详细HTML报告已生成到: %YELLOW%%COVERAGE_DIR%\html\index.html%NC% echo. REM 生成SVG覆盖率徽章 echo %BLUE%生成覆盖率徽章...%NC% REM 通过PowerShell生成SVG徽章 powershell -Command "& { function Generate-Badge($title, $percent, $fileName) { $color = 'red' if ([double]$percent -ge 90.0) { $color = 'brightgreen' } elseif ([double]$percent -ge 80.0) { $color = 'green' } elseif ([double]$percent -ge 70.0) { $color = 'yellowgreen' } elseif ([double]$percent -ge 60.0) { $color = 'yellow' } elseif ([double]$percent -ge 50.0) { $color = 'orange' } $svg = @\" $title $title $percent% $percent% \"@ $svg | Out-File -FilePath \"%COVERAGE_DIR%\badges\$fileName\" -Encoding utf8 } Generate-Badge '行覆盖率' '%LINES_PERCENT%' 'line-coverage.svg' Generate-Badge '函数覆盖率' '%FUNCTIONS_PERCENT%' 'function-coverage.svg' Generate-Badge '分支覆盖率' '%BRANCHES_PERCENT%' 'branch-coverage.svg' }" echo 覆盖率徽章已生成到: %YELLOW%%COVERAGE_DIR%\badges%NC% echo. REM 检查是否满足覆盖率要求 powershell -Command "& { if (([double]'%LINES_PERCENT%' -ge [double]'%LINES_TARGET%') -and ([double]'%FUNCTIONS_PERCENT%' -ge [double]'%FUNCTIONS_TARGET%') -and ([double]'%BRANCHES_PERCENT%' -ge [double]'%BRANCHES_TARGET%')) { Exit 0 } else { Exit 1 } }" if %ERRORLEVEL% equ 0 ( echo %GREEN%覆盖率目标达成!%NC% ) else ( echo %YELLOW%覆盖率未达目标!%NC% ) REM 不将覆盖率不足视为错误,但会发出警告 exit /b 0