RenderDoc 自动化测试系统完全指南:demos 构建、测试运行与用例编写
【免费下载链接】renderdocRenderDoc is a stand-alone graphics debugging tool.项目地址: https://gitcode.com/gh_mirrors/re/renderdoc
本指南以 util/test/README.md 为骨架,结合仓库内 util/test/run_tests.py、util/test/rdtest、util/test/demos 与 util/test/tests 等源码,系统讲解 RenderDoc 图形调试工具的自动化测试体系。你将掌握:如何在不同平台构建 demos 测试程序、如何用run_tests.py精确筛选并运行测试、如何理解测试产物与报告,以及如何从零添加一个属于自己的渲染回归测试。
测试体系总览:demos + Python 用例的双层架构
RenderDoc 的自动化测试不是一个单体程序,而是由两层紧密配合的组件构成:
- demos 程序(C++):一个包含大量"小而全"的 API 用法演示的独立可执行文件。每个 demo 用某一种图形 API(D3D11、D3D12、OpenGL、Vulkan)完成一件简单的事,例如画一个三角形、测试常量缓冲区或验证纹理格式。demos 的源码位于 util/test/demos,按 API 分目录组织(
d3d11/、d3d12/、gl/、vk/),其构建脚本是 util/test/demos/CMakeLists.txt。 - Python 测试用例(
tests/):位于 util/test/tests,每个用例通常与一个 demo 一一对应。用例驱动 RenderDoc 的 Python 模块(renderdoc与pyrenderdoc)打开 demo 产生的捕获文件,对回放结果进行断言——例如检查顶点着色器输出、像素拾取值、着色器调试轨迹等。
两者通过"测试名"关联:Python 用例类中的demos_test_name属性指向 demos 中的同名 demo,例如 tests/Vulkan/VK_Simple_Triangle.py 中的demos_test_name = 'VK_Simple_Triangle'。测试运行时,框架会调用 demos 程序执行对应 demo 并自动捕获若干帧,生成 .rdc 捕获文件交给 Python 用例回放校验。
从 util/test/rdtest/runner.py 的get_tests()可以看出测试的收集机制:框架扫描所有已加载模块,凡是testcase.TestCase的子类且未标记internal的类都会被视为一个测试用例,并按"慢测试优先、名字排序"排列。
构建 demos 测试程序
大多数测试都依赖 demos 程序,因此第一步是把它编译出来。
Windows 平台
直接打开 util/test/demos/demos.sln(实际文件为util/test/demos/demos.vcxproj所在的解决方案)用 Visual Studio 编译即可。官方说明没有必须的外部依赖,开箱即用。
Linux 与 Apple 平台
使用 CMake 构建,命令如下:
cmake -Bbuild -Hdemos make -C build在 Linux 上需要安装以下库(它们同时也是编译带 GL 支持的 RenderDoc 所需,通常你已经装好):
libX11libxcblibX11-xcb
从 util/test/demos/CMakeLists.txt 可以看到,Unix 构建会通过target_compile_definitions启用VK_USE_PLATFORM_XCB_KHR,并链接-lX11 -lxcb -lX11-xcb。
可选的 shaderc 软依赖
注意:目前存在一个软性外部依赖。如果 demos 程序没有链接 shaderc,它会在运行时调用glslc命令把着色器编译为 SPIR-V;缺少 shaderc 时,依赖运行时着色器编译的部分测试会被自动禁用。
- 目前只有Windows支持链接 shaderc,并且是自动的——只要在
$VULKAN_SDK环境变量指定的目录下能找到 shaderc 即可。 - 对于 Linux/Apple,util/test/demos/CMakeLists.txt 也保留了探测
3rdparty/shaderc/linux64|linux32目录的逻辑:若存在libshaderc_combined.a则定义HAVE_SHADERC并链接进去;否则回退到运行时调用glslc。
Android 平台
demos 也支持构建为 Android APK(对应 util/test/demos/android 目录)。CMake 逻辑要求设置JAVA_HOME、Android SDK 与 NDK 环境变量,默认 ABI 为arm64-v8a,并通过 util/test/README.md 中描述的--adb-device参数在真机/模拟器上运行测试。
让测试能找到 demos 二进制
Linux/Apple 上运行测试前,需要把demos_x64的构建输出目录加入PATH;或者更推荐使用--demos-binary参数直接指定demos_x64的文件路径。在 util/test/run_tests.py 中该参数默认值为空字符串,运行时若给出则会被os.path.realpath解析为绝对路径(util/test/run_tests.py)。
运行测试:run_tests.py 详解
运行测试的命令行入口是 util/test/run_tests.py。注意:运行测试所用的 Python 版本必须与构建被测 RenderDoc 时使用的 Python 版本一致;Windows 上还必须匹配位数——64 位 RenderDoc 需要 64 位 Python,32 位同理。仓库在 Windows 上默认随附 Python 3.6。
常用参数
| 参数 | 简写 | 说明 |
|---|---|---|
--renderdoc | -r | RenderDoc 原生库所在路径,用于修改操作系统库搜索路径。Windows 示例:--renderdoc /path/to/renderdoc/x64/Development |
--pyrenderdoc | -p | renderdocPython 模块所在路径。Windows 示例:--pyrenderdoc /path/to/renderdoc/x64/Development/pymodules |
--list | -l | 列出全部可用测试后退出 |
--test_include | -t | 用正则表达式筛选要运行的测试,只运行匹配的用例;省略则运行全部 |
--test_exclude | -x | 用正则表达式排除测试;省略则不做排除 |
--in-process | - | 在同一个 Python 进程内运行测试(默认每个测试派生子进程);主要用于调试 |
--slow-tests | - | 包含标记为可能长时间运行的测试(默认排除,保证快速回归) |
--data | - | 参考数据目录,默认为脚本旁的data/ |
--artifacts | - | 输出产物目录,默认为脚本旁的artifacts/ |
--temp | - | 临时工作目录,默认为脚本旁的tmp/ |
--data-extra | - | 额外数据目录,存放无法提交进仓库的大体积捕获文件,默认data_extra/ |
--demos-binary | - | 构建好的 demos 二进制路径 |
--adb-device | - | 指定 ADB 设备运行测试(代替本机);设置后--demos-binary应指向 demo APK |
这些参数在 util/test/run_tests.py 中均有对应的 argparse 定义,除上表外还支持:
--parallel N(-j):并行运行 N 个子进程测试(util/test/run_tests.py);--test-timeout:等待测试输出的超时秒数,默认 90(util/test/run_tests.py);--demos-timeout:等待 demos 运行完成的超时;--debugger:开启调试器模式,框架不再捕获异常,便于在 IDE 中单步调试测试本身(util/test/run_tests.py)。
Windows 上的典型调用方式:
python run_tests.py --pyrenderdoc /path/to/renderdoc/x64/Development/pymodules \ --renderdoc /path/to/renderdoc/x64/Development库与模块路径的解析逻辑
源码层面,--renderdoc与--pyrenderdoc的处理值得注意(util/test/run_tests.py):
- 两者都既接受文件也接受目录;传入文件时会取所在目录。
--renderdoc指定后会把目录追加到PATH;在 Python 3.8+ 的 Windows 上还会调用os.add_dll_directory加入 DLL 搜索路径(因为 Python 3.8 不再搜索 PATH)。- 若只给了
--renderdoc而未给--pyrenderdoc,Windows 下会默认尝试<renderdoc>/pymodules,其他平台则默认使用<renderdoc>本身。 - 如果两者都没指定,Windows 下还会尝试从仓库默认构建位置(
x64/Development/pymodules或x64/Release/pymodules)自动导入。
如果rdtest模块导入失败,脚本会在 artifacts 目录生成一个output.log.html并提示用--pyrenderdoc或--renderdoc指定路径后退出(util/test/run_tests.py)。
运行时的内部机制
- 进程隔离:默认情况下每个测试在独立子进程中运行(util/test/rdtest/runner.py),通过
--internal_run_test与--internal_thread内部参数重新启动自身执行单个测试,这样即使测试崩溃也不会拖垮整个测试运行。 - 超时与崩溃处理:主进程持续监控子进程输出,超过
--test-timeout无输出则杀掉子进程并标记超时;返回码非 0/1/100 会被判定为可能崩溃(util/test/rdtest/runner.py)。 - 测试筛选:
test_include/test_exclude会被编译为正则表达式,逐一匹配测试类名做大小写不敏感过滤(util/test/rdtest/runner.py)。 - Vulkan 图层注册:运行前会检查是否需要注册 Vulkan 层,必要时自动注册;Windows 上若需要提权会触发 UAC 提示(util/test/rdtest/runner.py)。
- 目录清理:每次运行开始,
tmp/与artifacts/都会被彻底清空(util/test/rdtest/runner.py),所以不要在这两个目录放任何想保留的东西。
理解测试产物与报告
运行结束后,--artifacts指向的目录(默认artifacts/)保存全部输出:
- 主日志文件
output.log.html:内容大部分是纯文本,但内嵌了少量 JavaScript 以便在浏览器中友好展示; - 日志渲染所需的 CSS/JS(
testresults.css、testresults.js,见 util/test/rdtest/testresults.css)与所有图片 diff 都会复制到同一目录,因此artifacts 目录是自包含的,可以直接打包或拷贝到其他机器上用浏览器打开。
日志头部会记录被测 RenderDoc 的版本号、Git 提交哈希、平台信息、各 API 驱动版本以及 demos 二进制路径(util/test/rdtest/runner.py),结尾输出汇总统计total/fail/skip/time,若有失败用例会列出名字,并以退出码 1 表示存在失败(util/test/rdtest/runner.py)。
添加一个测试:从 demo 到 Python 用例
编写 demos 示例
demos 项目自带辅助库(util/test/demos/test_common.h、util/test/demos/test_common.cpp),因此最佳实践是复制一个现有 demo 再修改,而不是从零开始。官方建议:
- 避免"uber-demo"——一个 demo 只做一件简单的事,便于定位问题;
- demo 与 Python 测试通常 1:1 对应,例如 util/test/demos/vk/vk_simple_triangle.cpp 对应 util/test/tests/Vulkan/VK_Simple_Triangle.py。
demos 可执行文件支持--list-raw参数(util/test/demos/main.cpp)以纯文本列出可用测试名;util/test/rdtest/runner.py 的fetch_tests()就是调用它解析出Name、Available、AvailMessage三列的 TSV,用于在运行前检查某个 demo 是否已编译进 demos 程序。
编写 Python 测试用例
同样复制现有用例修改。一个典型用例继承rdtest.TestCase并实现check_capture()(见 util/test/rdtest/testcase.py 基类定义):
import renderdoc as rd import rdtest class VK_Simple_Triangle(rdtest.TestCase): demos_test_name = 'VK_Simple_Triangle' def check_capture(self): # 获取最后一个 action,设置帧事件,然后校验三角形像素颜色 last_action = self.get_last_action() self.set_event(last_action.eventId, True) self.check_triangle(out=last_action.copyDestination) ...框架提供的两种用例编写模式(util/test/rdtest/testcase.py):
- 实现
run():完全自定义执行流程; - 实现
get_capture()+check_capture():使用默认的run(),它自动运行 demo、捕获指定帧、打开捕获文件并调用check_capture()校验。
demos_test_name非空时,默认的get_capture()会通过capture.run_and_capture执行 demos 并抓取demos_frame_cap(默认 5)帧(util/test/rdtest/testcase.py)。用例还可以通过类属性调整行为:slow_test(标记慢测试)、demos_frame_count、demos_captures_expected、demos_timeout等。
基类提供了大量开箱即用的断言工具,例如check_triangle()(默认期望深灰背景上的绿色三角形,util/test/rdtest/testcase.py)、check_pixel_value()、check_mesh_data()(对比后 VS 顶点数据,util/test/rdtest/testcase.py)、check_final_backbuffer()(与参考图对比最终后备缓冲,util/test/rdtest/testcase.py)等。
添加参考图片对比测试
需要与参考图片对比的测试,流程是:
- 第一次不带参考图运行,测试会输出它将要对比的图片;
- 用
pngcrush压缩这张图(务必保证 RGBA 输出被保留),以减少仓库体积; - 将处理后的图片放入
--data目录下以测试类名命名的子目录中——util/test/rdtest/testcase.py 的get_ref_path()会拼出data/<ClassName>/<name>的参考路径。
参考数据目录在运行时不会被修改;而tmp/与artifacts/会被清空重建(util/test/run_tests.py 的参数注释也明确说明了这一点)。
许可与第三方依赖
RenderDoc 以 MIT 许可证发布(见仓库根目录 LICENSE.md)。测试体系涉及的第三方组件及许可证如下(详见 util/test/README.md 末尾):
- GLAD(扩展加载):MIT;
- LZ4(压缩):BSD;
- volk(Vulkan 加载):MIT;
- nuklear(demos 启动器 UI):MIT;
- shaderc(SPIR-V 着色器编译):Apache-2.0;
- pypng(Python 测试的 PNG 读写库,纯依赖):MIT;
- demo 视频片段来自 Caminandes(Creative Commons Attribution 3.0 许可)。
常见问题速查
- 测试说找不到
renderdoc模块:检查--pyrenderdoc是否指向正确的pymodules目录,或--renderdoc是否指向构建输出目录(util/test/run_tests.py)。 - 部分测试被跳过且提示 demo 未编译:
fetch_tests()通过--list-raw探测每个 demo 是否可用(util/test/rdtest/runner.py),未编译的 demo 对应测试会被跳过;重新构建 demos 并确保路径正确即可。 - Vulkan 测试报图层注册失败:需要在有管理员权限的环境运行,或先手动注册 Vulkan 层(util/test/rdtest/runner.py)。
- 想跑完整回归但时间不够:默认会排除慢测试;需要时可加
--slow-tests显式包含。 - 在 Android 设备上运行:使用
--adb-device <设备ID>并把--demos-binary指向构建出的 demo APK。
以上内容完整覆盖了 RenderDoc 测试体系从构建、运行到扩展的闭环。如需深入某个细节,可直接阅读 util/test/run_tests.py、util/test/rdtest/testcase.py 与 util/test/demos/CMakeLists.txt 的对应源码。
【免费下载链接】renderdocRenderDoc is a stand-alone graphics debugging tool.项目地址: https://gitcode.com/gh_mirrors/re/renderdoc
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考