尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

用 Dear ImGui Test Engine 为 ImGui 应用构建自动化测试:以 ImHex 集成为例

用 Dear ImGui Test Engine 为 ImGui 应用构建自动化测试:以 ImHex 集成为例 桌面应用开发工具逆向工程【免费下载链接】ImHex A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.项目地址https://gitcode.com/GitHub_Trending/im/ImHex点击查看免费下载Dear ImGui Test Engine 是一套专为 Dear ImGui 及其上层应用游戏、引擎、工具设计的自动化测试系统通过向 ImGuiIO 注入鼠标、键盘、手柄输入来以最终用户的视角驱动你的应用完成点击、勾选、输入、菜单操作等一系列动作。本文基于仓库内嵌的 lib/third_party/imgui/imgui_test_engine/README.md 展开并结合 ImHex 仓库中该引擎的源码集成方式讲解其核心 API、自动化代码范式、运行模式以及如何在 ImHex 这样的桌面应用中接入与注册测试读完即可上手编写自己的 GUI 自动化测试。一、这是什么为 Dear ImGui 应用而生的自动化与测试系统Dear ImGui 常常被深度接入到应用的低层子系统渲染循环、输入系统、窗口管理甚至引擎内核中。Test Engine 正是利用了这一特性它从最终用户的角度与 UI 交互——注入模拟的鼠标/键盘/手柄输入到 ImGui 的 IO 系统中然后想办法完成目标动作例如用 CtrlTab 切换到目标窗口、把遮挡窗口移开、滚动定位目标控件、查询其打开状态等。这意味着你不需要为测试编写专用的钩子而是直接驱动真实 UI。从 README 的 Overview 可以归纳出它的核心设计目标自动化与自测一体既用于自动化测试第三方 ImGui 应用也被作者用于对 Dear ImGui 自身做回归测试、降低改动引入的回归、方便贡献者自测端到端交互交互绝大部分从最终用户视角出发模拟真实操作而非直接调用内部函数用途广泛冒烟测试smoke testing、集成/功能测试、自动化任务批量运行、录制视频等都适用能测试 UI 上暴露的一切由于你的应用本身受 Dear ImGui 控制自动化它也就等于自动化了应用/引擎中暴露在 UI 上的任何能力窗口模式与无头模式headless既可以跑在正常窗口应用中观看、录屏也可以在无渲染的 CI 服务器/控制台环境运行 GUI 测试多档速度以人类可观看速度运行便于调试、录屏或以快速模式运行鼠标瞬移、跳过延时截图与视频/GIF 导出可用于部分断言式测试也可为文档生成素材或向团队通告界面变化需要频繁更新的素材最适合由脚本自动生成而不是手工截图裁剪高层级命令编程既能写MenuCheck(Edit/Options/Enable Grid)这种高层命令也能做程序化查询如列出该区域所有可打开的项然后全部打开因此从简单的冒烟测试打开我们所有工具到复杂的交互测试与 xxx 交互并校验结果都能覆盖活的教程/演示脚本可以在真实用户应用上运行来展示功能性能工具与查看器附带性能记录/对比工具可选需要 ImPlot可用于跨构建、跨分支对比性能。二、仓库内嵌的组织结构上游项目由四个部分组成本仓库内嵌的是其中作为库的核心部分上游组成部分作用本仓库内嵌情况imgui_test_engine/Dear ImGui 测试引擎 / 自动化系统库已内嵌于 lib/third_party/imgui/imgui_test_engine/包含include/、source/、CMakeLists.txt、LICENSE.txtimgui_test_suite/官方测试套件应用未内嵌上游仓库组成部分app_minimal/演示如何集成测试引擎的最小应用未内嵌上游仓库组成部分shared/应用共享的 C 辅助代码未内嵌上游仓库组成部分在本仓库中测试引擎通过 lib/third_party/imgui/CMakeLists.txt 以add_subdirectory(imgui_test_engine)方式纳入构建lib/third_party/imgui/imgui_test_engine/CMakeLists.txt 用IMHEX_ENABLE_IMGUI_TEST_ENGINE AND NOT IMHEX_EXTERNAL_PLUGIN_BUILD门控编译目标为imgui_test_engine静态对象库要求 C23并对外定义IMGUI_TEST_ENGINE1宏供集成方按宏裁剪代码。三、第一个自动化测试README 示例逐行拆解README 给出了自动化代码的快速概览这是理解整个 API 的最短路径ImGuiTest* test IM_REGISTER_TEST(e, demo_test, test1); test-TestFunc [](ImGuiTestContext* ctx) { ctx-SetRef(My Window); // 设置基准路径之后无需再写完整路径 ctx-ItemClick(My Button); // 在 My Window 内点击 My Button ctx-ItemCheck(Node/Checkbox); // 打开 Node找到 Checkbox若未勾选则勾选它 ctx-ItemInputValue(Slider, 123); // 找到 Slider 并设置值为 123 IM_CHECK_EQ(app-SliderValue, 123); // 在应用侧校验数值 ctx-MenuCheck(//Dear ImGui Demo/Tools/About Dear ImGui); // 显示 About 窗口假定 Demo 窗口已打开 };逐行要点IM_REGISTER_TEST(e, demo_test, test1)向引擎e注册一个类别为demo_test、名为test1的测试。在源码中该宏展开为ImGuiTestEngine_RegisterTest(engine, category, name, __FILE__, __LINE__)见 imgui_te_engine.h注册时自动记录源文件与行号用于 UI 中打开源码跳转。SetRef(My Window)设置基准base reference之后所有相对路径都基于该窗口解析。ItemClick/ItemCheck/ItemInputValue分别对应点击、勾选仅在未勾选时操作、输入数值三个高层动作由ImGuiTestContext::ItemAction()统一调度。IM_CHECK_EQ(app-SliderValue, 123)断言应用侧状态。这类检查宏失败时不仅返回 false还会自动输出左右两侧表达式的实际值便于定位问题。MenuCheck走菜单路径操作//前缀表示从根路径开始脱离当前基准用于跨窗口定位。Named References用路径描述任何控件所有接收控件引用的函数都使用ImGuiTestRef弱引用既可传预哈希 ID 也可传字符串路径见 imgui_te_context.h。字符串路径是日常最常用的写法其语义在源码注释中给出了明确规则写法语义ItemClick(Window/Button)点击Window/Button绝对路径SetRef(Window)后ItemClick(Button)点击Window/Button相对当前基准SetRef(Window)后ItemClick(/Button)等价于点击Window/Button/为基准内路径SetRef(Window)后ItemClick(//Button)点击/Button//表示脱离基准、从根开始SetRef(//$FOCUSED)后ItemClick(Button)在当前焦点窗口中点击Button此外路径中间层级会自动展开例如ItemClick(Hello/OK)若找不到OK会先自动打开Hello可用ImGuiTestOpFlags_NoAutoOpenFullPath关闭见 imgui_te_context.h对未展开的窗口还会自动恢复展开NoAutoUncollapse可关闭。这些默认行为让测试脚本写起来更像人的操作。四、ImGuiTestContext测试编写者唯一的主要接口imgui_te_context.h 明确说明这是你的测试将要使用的主要甚至唯一接口。从源码看ImGuiTestContext提供了完整的操作面可分以下几组1. 主控制与状态查询Finish(status)手动结束测试并设定状态对只有GuiFunc无TestFunc的测试尤其重要配合ImGuiTestFlags_NoAutoFinish使用RunChildTest(name, flags)在当前测试中运行另一个测试实验性支持ImGuiTestRunFlags_ShareVars/ShareTestContext共享变量与上下文IsError()/IsWarmUpGuiFrame()/IsFirstTestFrame()等查询测试运行状态。注意默认情况下测试引擎会先跑两帧GuiFunc()WarmUp 帧再进入TestFunc()可用ImGuiTestFlags_NoGuiWarmUp禁用见 imgui_te_engine.h。2. 鼠标、键盘与导航输入鼠标MouseMove平滑移动、MouseTeleportToPos瞬移Fast 模式默认行为、MouseClick/DoubleClick/MouseDown/MouseUp、MouseDragWithDelta、MouseWheel、MouseMoveToVoid移动到无窗口的空白处键盘KeyDown/KeyUp/KeyPress/KeyHold、KeyChars输入字符、KeyCharsReplaceEnter清空原字段后输入并回车等导航SetInputModeMouse/Keyboard/Gamepad 三种模式、NavMoveTo、NavActivate、NavInput。在 Keyboard/Gamepad 模式下ItemClick等动作改用导航系统而非鼠标完成引擎会在后台处理鼠标速度、抖动、滚动速度、打字速度等参数见下文 IO 配置非 Fast 模式下动作看起来就像真人操作。3. 窗口、弹窗、滚动与停靠窗口WindowInfo含子窗口路径信息、WindowClose/WindowCollapse/WindowFocus/WindowBringToFront/WindowMove/WindowResize、GetWindowTitlebarPoint等弹窗PopupCloseOne/PopupCloseAll滚动ScrollTo/ScrollToX/ScrollToY、ScrollToTop/ScrollToBottom、ScrollToItem等测试引擎会先滚动定位再操作目标这正是像人一样找路的体现停靠DockingDockInto、UndockWindow、DockClear等需IMGUI_HAS_DOCK编译开关。4. 控件操作与批量动作单控件ItemAction统一调度Hover/Click/DoubleClick/Check/Uncheck/Open/Close/Input/NavActivate九类动作枚举见 imgui_te_context.h其上封装了ItemClick/ItemDoubleClick/ItemCheck/ItemUncheck/ItemOpen/ItemClose/ItemInput/ItemNavActivate读值/写值ItemInputValue(ref, int/float/const char*)直接设值ItemReadAsInt/ItemReadAsFloat/ItemReadAsString/ItemReadAsScalar通过选中-复制-解析的方式读取 Slider/Drag/InputText 的当前值临时使用内部剪贴板读后恢复状态查询ItemExists/ItemIsChecked/ItemIsOpened批量动作ItemActionAllImGuiTestActionFilter按深度、通过次数、状态标志过滤、ItemOpenAll/ItemCloseAll——这就是 README 所说列出可打开的项然后全部打开式程序化查询的落点拖拽ItemDragAndDrop、ItemDragOverAndHold、ItemHold等菜单族MenuClick/MenuCheck/MenuUncheck/MenuCheckAll下拉框ComboClick/ComboClickAll表格TableClickHeader/TableSetColumnEnabled/TableResizeColumn/TableGetSortSpecs标签栏TabClose/TabBarCompareOrder。5. 截图与视频捕获CaptureScreenshot整窗或指定窗口截图、CaptureBeginVideo/CaptureEndVideo视频录制、CaptureAddWindow/CaptureSetExtension/CaptureReset多段捕获组合底层由ImGuiScreenCaptureFunc回调驱动应用必须在交换帧缓冲后调用ImGuiTestEngine_PostSwap()见 imgui_te_engine.h。6. 调试辅助IM_SUSPEND_TESTFUNC()宏可以临时挂起TestFunc让开发者用鼠标亲自检查当前 GUI 状态然后点Continue恢复执行实现基于ctx-SuspendTestFunc()见 imgui_te_context.h。五、IM_CHECK 断言宏失败即带现场证据Test Engine 提供了一套丰富的断言宏定义见 imgui_te_context.h标量比较IM_CHECK_EQ/NE/LT/LE/GT/GE失败时自动打印左右表达式与真实值以及_NO_RET变体失败不中断和_RETV变体失败返回指定值字符串比较IM_CHECK_STR_EQ/NE、_SILENT变体成功时不打印日志浮点比较IM_CHECK_FLOAT_EQ_EPS/NE_EPS/NEAR带 epsilon 容差通用错误IM_ERRORF(fmt, ...)直接记录格式化错误并触发IM_DEBUG_BREAK()基础检查IM_CHECK(expr)失败即记录并 return。所有宏都包在do { } while(0)中可当作普通单语句使用如if (x) IM_CHECK(A); else IM_CHECK(B);。断言失败时引擎默认会触发调试器断点IM_DEBUG_BREAK配合ImGuiTestEngineIO::ConfigBreakOnError/ConfigStopOnError可控制行为。六、引擎层 API 与配置从初始化到运行引擎层接口应用初始化、主循环使用在 imgui_te_engine.h 中流程清晰创建与销毁ImGuiTestEngine_CreateContext()/ImGuiTestEngine_DestroyContext()后者需在ImGui::DestroyContext()之后调用以便保存引擎自身 ini 数据绑定与启动ImGuiTestEngine_Start(engine, ui_ctx)绑定 ImGui 上下文并启动协程/ImGuiTestEngine_Stop(engine)每帧驱动ImGuiTestEngine_PostSwap(engine)在帧缓冲交换后调用处理截图与ScreenCaptureFunc回调注册测试IM_REGISTER_TEST(engine, category, name)宏 →ImGuiTestEngine_RegisterTest排队执行ImGuiTestEngine_QueueTest/QueueTests(group, filter)按组 通配过滤批量排队查询状态IsTestQueueEmpty/IsUsingSimulatedInputs/GetResultSummary返回CountTested、CountSuccess、CountInQueue/GetTestList/GetTestQueue崩溃处理ImGuiTestEngine_InstallDefaultCrashHandler()/ImGuiTestEngine_CrashHandler()——即使测试中途应用崩溃也能保证既往测试结果被正确导出。ImGuiTestEngineIO关键配置项所有配置集中在ImGuiTestEngineIOimgui_te_engine.h核心参数如下配置项默认值含义ConfigRunSpeedImGuiTestRunSpeed_Fast运行速度Fast最快鼠标瞬移跳过延时/ Normal可观看速度用于调试/ Cinematic动作间停顿用于教程ConfigVerboseLevelWarning日志详细级别Silent→Error→Warning→Info→Debug→Trace对应-v0~-v4命令行参数ConfigStopOnErrorfalse出错时停止后续排队测试ConfigBreakOnErrorfalse出错时触发调试器断点ConfigWatchdogWarning/ConfigWatchdogKillTest/ConfigWatchdogKillApp30s / 60s /FLT_MAX看门狗超时警告 / 尝试终止当前测试 / 终止整个应用交互式 GUI 应用建议调大MouseSpeed/ScrollSpeed/TypingSpeed600 / 1400 / 20像素或字符每秒非 Fast 模式下的模拟速度ActionDelayShort/ActionDelayStandard0.15s / 0.40s动作间短/标准延时ConfigCaptureEnabledtrue截图/录像总开关关掉可避免保存大 PNG 的耗时VideoCaptureEncoderPath/VideoCaptureEncoderParams/GifCaptureEncoderParams空视频/GIF 编码器如 ffmpeg路径与参数VideoCaptureExtension.mp4视频文件扩展名ConfigFixedDeltaTime0.0固定 delta time替代按墙钟计算ConfigMouseDrawCursortrue运行时绘制软件鼠标光标ExportResultsFilename/ExportResultsFormat空结果导出文件名与格式注册后崩溃处理器也会自动导出GitBranchName空分支名写入性能采样 CSVPerfStressAmount1测试中提交的控件数量缩放系数输出侧还有三个只读状态IsRunningTests正在跑测试、IsRequestingMaxAppSpeedFast 模式下请求应用跳过 vsync 甚至跳过渲染、IsCapturing正在捕获。七、性能工具与结果导出Perf 工具ImGuiTestContext::PerfCalcRef()/PerfCapture(category, name, csv_file)见 imgui_te_context.h配合ImGuiTestEngineIO::PerfStressAmount与性能查看器源码位于 source/imgui_te_perftool.cpp需要 ImPlot可用于跨构建、跨分支的渲染性能对比结果导出导出器实现在 source/imgui_te_exporters.cpp配合崩溃处理器保证异常退出时结果不丢。八、ImHex 如何集成 Test Engine仓库源码实例本仓库把 Test Engine 作为一个可选的内部组件接入 ImHex链路清晰可作为如何在大型桌面应用中集成的参考实现构建集成lib/libimhex/CMakeLists.txt 中target_link_libraries(libimhex PUBLIC imgui_test_engine)将引擎链接进 libimhexlib/third_party/imgui/imgui_test_engine/CMakeLists.txt 以IMHEX_ENABLE_IMGUI_TEST_ENGINE选项门控并对外定义IMGUI_TEST_ENGINE1。事件桥接lib/libimhex/include/hex/api/events/events_lifecycle.hpp 声明了EventRegisterImGuiTests(ImGuiTestEngine*)事件——引擎初始化完成后广播各测试代码通过订阅该事件完成注册。测试注册封装lib/libimhex/include/hex/test/tests.hpp 在#if defined(IMGUI_TEST_ENGINE)下提供ImGuiTestSequence模板构造时记录std::source_location文件行号订阅上述事件事件回调中调用ImGuiTestEngine_RegisterTest(engine, category, name, file, line)并把TestFunc绑定为用户传入的函数对象。这把引擎的 C API 包装成了声明式的 C 测试序列测试只需书写类别 名称 函数体。Hook 桩lib/libimhex/source/helpers/imgui_hooks.cpp 提供ImGuiTestEngineHook_ItemAdd/ItemInfo/Log/FindItemDebugLabel的空实现未启用引擎时的兼容桩说明引擎依赖 Dear ImGui 内部的 Test Engine 专用 Hook 点对应 imgui_internal.h 中[SECTION] Test Engine specific hooks来采集控件 ID、标签与几何信息。运行时开关lib/libimhex/include/hex/ui/imgui_imhex_extensions.h 与 lib/libimhex/source/ui/imgui_imhex_extensions.cpp 提供ImGuiTestEngine::setEnabled(bool)/isEnabled()允许在运行时启停测试引擎功能。从这套集成可以看出一个通用模式用事件EventRegisterImGuiTests解耦引擎初始化与测试注册时机用std::source_location自动携带源码定位用编译宏IMGUI_TEST_ENGINE保证非测试构建零开销。这也印证了 README 中未来命令将更标准化、可存入数据文件、可从其他语言调用的前瞻性设计——本仓库的封装已经向声明式方向迈了一步。九、状态与许可当前为 C API作者预期未来命令将更标准化、存储于数据文件、并可从其他语言调用该项目自 2018 年开发使用2022 年底才公开作者承诺尽力使其满足用户需求但也明示你会遇到问题和短板欢迎反馈以改进软件与文档许可分两块imgui_test_engine库目录采用 Dear ImGui Test Engine License对个人、教育、开源及小型企业免费大型企业需购买授权销售所得用于资助 Dear ImGui 的开发测试套件及其余目录采用 MIT License。本仓库内嵌的 LICENSE 文件位于 lib/third_party/imgui/imgui_test_engine/LICENSE.txt。小结Dear ImGui Test Engine 的价值在于它把测试 UI还原为操作 UI——一切交互都以最终用户视角通过注入输入完成因此你既能在 CI 上无头跑冒烟测试也能在本地以可观看速度调试、录屏、导出素材还能借助 Perf 工具对比性能。结合 ImHex 的集成实例可以看到接入一个既有桌面应用只需四步构建链接引擎、事件广播、声明式注册测试、运行时开关。对任何深度依赖 Dear ImGui 的应用而言这套系统都是你能够自动化你的应用 你可以测试应用中暴露的一切的务实落地。赞分享桌面应用开发工具逆向工程【免费下载链接】ImHex A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.项目地址https://gitcode.com/GitHub_Trending/im/ImHex点击查看免费下载相关推荐如何使用Dear ImGui Test Engine构建可靠UI2023终极自动化测试指南如何使用Dear ImGui Test Engine构建可靠UI2023终极自动化测试指南 Dear ImGui作为一款轻量级、无依赖的C图形用户界面库UI组件前端桌面应用图形学Hermes 仓库中的 cimgui为 Dear ImGui 自动生成的 C API 包装层及其在基准测试 GUI 中的应用Hermes 仓库中的 cimgui为 Dear ImGui 自动生成的 C API 包装层及其在基准测试 GUI 中的应用 导读 cimgui https:语言运行时编译器移动开发Dear ImGui Emscripten实战将C界面直接编译为Web应用Dear ImGui Emscripten实战将C界面直接编译为Web应用 痛点C GUI应用难以部署到Web环境 你是否曾经遇到过这样的困境用CUI组件前端桌面应用图形学上一篇重构Jaeger测试框架从零散到体系化的演进之路下一篇如何构建企业级工作流引擎bknd自动化平台的3大核心优势深度解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表