Files
Alicho/tests/scripts/generate_coverage.bat
2025-10-28 10:27:49 +08:00

261 lines
9.5 KiB
Batchfile
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@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 = @\"
<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"120\" height=\"20\" role=\"img\">
<linearGradient id=\"s\" x2=\"0\" y2=\"100%\">
<stop offset=\"0\" stop-color=\"#bbb\" stop-opacity=\".1\"/>
<stop offset=\"1\" stop-opacity=\".1\"/>
</linearGradient>
<clipPath id=\"r\">
<rect width=\"120\" height=\"20\" rx=\"3\" fill=\"#fff\"/>
</clipPath>
<g clip-path=\"url(#r)\">
<rect width=\"70\" height=\"20\" fill=\"#555\"/>
<rect x=\"70\" width=\"50\" height=\"20\" fill=\"#$color\"/>
<rect width=\"120\" height=\"20\" fill=\"url(#s)\"/>
</g>
<g fill=\"#fff\" text-anchor=\"middle\" font-family=\"Verdana,Geneva,DejaVu Sans,sans-serif\" text-rendering=\"geometricPrecision\" font-size=\"110\">
<text aria-hidden=\"true\" x=\"350\" y=\"150\" fill=\"#010101\" fill-opacity=\".3\" transform=\"scale(.1)\" textLength=\"600\">$title</text>
<text x=\"350\" y=\"140\" transform=\"scale(.1)\" fill=\"#fff\" textLength=\"600\">$title</text>
<text aria-hidden=\"true\" x=\"950\" y=\"150\" fill=\"#010101\" fill-opacity=\".3\" transform=\"scale(.1)\" textLength=\"430\">$percent%</text>
<text x=\"950\" y=\"140\" transform=\"scale(.1)\" fill=\"#fff\" textLength=\"430\">$percent%</text>
</g>
</svg>
\"@
$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