news 2026/9/13 5:33:54

cua-driver 跨操作系统工具面冒烟测试:per-OS 全工具 PASS/FAIL/SKIP 探测与基线回归对比

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
cua-driver 跨操作系统工具面冒烟测试:per-OS 全工具 PASS/FAIL/SKIP 探测与基线回归对比

cua-driver 跨操作系统工具面冒烟测试:per-OS 全工具 PASS/FAIL/SKIP 探测与基线回归对比

【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua

本篇基于 smoke 测试说明文档 讲解 cua-driver 的跨操作系统 CLI 冒烟测试体系:它与 MCP stdio 集成测试如何分工、macOS 冒烟脚本如何逐个探测全部已注册工具并归类为 PASS/FAIL/SKIP,以及如何通过基线结果文件 diff 捕获工具覆盖度回归。读完你可以理解这套"约 30 秒扫完全工具面"的验证策略,并能按同样方式为自己关心的 OS 增加一条冒烟跑道。

两层验证:MCP 集成测试 vs CLI 冒烟探测

smoke 目录的 README 开宗明义:这里的 runner 是对每一台宿主 OS 上 cua-driver完整工具面做一遍广撒网式的 PASS / FAIL / SKIP 探测。它明确说明了与 Rust 集成测试的分工边界:

  • 集成测试(位于libs/cua-driver/rust/crates/cua-driver/tests/)驱动 cua-driver 走MCP stdio 回路,断言具体的 UIA / AX 状态变化,属于"深而准"的行为验证;
  • 冒烟 runner驱动 cua-driver 走CLIcua-driver call <tool> <json>),走的是另一条代码路径——CLI 参数解析器加工具解析——用约 30 秒对每一个注册工具做一次广覆盖扫描。

两条路径的入口差异可以在源码中印证:CLI 侧的call子命令解析与工具名提取实现在 cli.rs(如finite_tool_name_from_args(&args(&["call", "click", r#"{\"x\":1}"#]))一类用例所覆盖的逻辑)。正因 CLI 与 MCP stdio 的入参解析、工具解析链路不同,冒烟测试的价值不是"重复集成测试",而是确保每一个注册工具都能被 CLI 正确寻址并干净退出——这是集成测试断言式覆盖难以低成本穷举的层面。

目录定位:smoke runner 在 fixture 体系中的位置

smoke 目录是 cua-driver 测试 fixture 体系的一部分。该 README 给出的整体布局是:

tests/fixtures/ ├── shared/ │ ├── scenarios.json # scenario ids, titles, and expected controls │ └── web/index.html # shared DOM for webview-style harnesses ├── apps/ │ ├── cross-platform/ │ │ ├── electron/ # Chromium/Electron host, CDP port 9223 │ │ └── tauri/ # native webview/Tauri host │ ├── linux/ │ │ └── gtk3/ # PyGObject GTK3 app │ ├── macos/ │ │ ├── appkit/ # single-file Swift AppKit app │ │ ├── swiftui/ # single-file SwiftUI app │ │ └── wkwebview/ # native WKWebView host for shared DOM │ └── windows/ │ ├── wpf/ # .NET WPF app │ ├── winui3/ # unpackaged WinUI3 app │ └── webview2/ # WPF + WebView2 host for shared DOM ├── build/ # host build scripts └── smoke/ # lightweight local smoke runners

关键点在于:fixture 是source-first的——构建脚本把本地产物暂存(stage)到libs/cua-driver/rust/test-apps/harness-<name>/,二进制本身不入库。smoke runner 所依赖的"受害应用"(victim app)正是这一暂存机制的产物。fixture 应用与暂存输出的映射关系在 fixture 应用总表中维护,例如 AppKit 源码在apps/macos/appkit,暂存输出为harness-appkit;完整应用矩阵(AppKit / SwiftUI / WKWebView / WPF / WinUI3 / WebView2 / GTK3 / Electron / Tauri)与各自覆盖的可访问性面(AX、UIA、AT-SPI 等)见该文件的表格。

构建方式在 fixture 构建说明中给出:macOS 上运行libs/cua-driver/tests/fixtures/build/macos.sh(支持--skip <name>--only <name>选择目标),Windows 上运行tests/fixtures/build/windows.ps1(支持-Skip参数)。宿主依赖方面,macOS 需要 Xcode 命令行工具,Electron 需要 Node.js/npm,Tauri 需要 Rust 工具链。

macOS 冒烟脚本:从前置条件到运行流程

当前 smoke 目录中随仓库提交的文件为 macos.sh。其脚本头部注释声明了它镜像scripts/linux-smoke.sh的形状与分类方式(即不同 OS 的 runner 保持同一结构、同一判定口径)。

前置条件(Prerequisites)

smoke README 与脚本头部注释一致地列出了三项 macOS 前置条件:

  1. tests/fixtures/build/macos.sh已运行,产出了libs/cua-driver/rust/test-apps/harness-appkit/(AppKit harness 应用);
  2. libs/cua-driver/rust/target/release/cua-driver已构建(debug 版本也可以,脚本会按 release → debug 顺序自动探测可执行文件);
  3. TCC 辅助功能(Accessibility)权限已授予 cua-driver 二进制

第三条附带一个重要的判定语义说明:如果 Accessibility 权限没给,AX 类工具会返回空树,但调用仍然干净退出——脚本会因此把它们记为PASS(因为退出码为 0 且输出无错误标记),并在输出中提示这一情况。这意味着读结果时要警惕"假阳性":全绿不代表无障碍权限一定就绪。

运行流程

脚本的主流程可以概括为六个阶段(见 macos.sh 全文):

  1. 定位二进制并校验。从仓库根推导target/release/cua-driver,不存在则回退 debug;再校验 harness 可执行文件CuaTestHarness.AppKit.app/Contents/MacOS/CuaTestHarness.AppKit是否就绪,缺失时直接打印对应的构建命令并退出。
  2. 拉起受害应用。后台启动 AppKit harness,sleep 1.5等待窗口就绪,并通过list_windows工具以 harness 的 PID 反查真实窗口号(用python3解析返回 JSON 中title含 "AppKit" 的窗口),随后执行start_session建立macos-smoke会话。
  3. group 1:无参/配置类工具。遍历check_permissionsget_screen_sizeget_cursor_positionget_configget_recording_statelist_appslist_windows及带 session 参数的get_agent_cursor_state——这类工具信息性强、总是安全。
  4. group 2:setter 工具。如set_config {"max_image_dimension":1024}set_agent_cursor_enabledset_agent_cursor_themetheme_id: cua.default)、set_agent_cursor_motionstop_recording
  5. group 3:应用生命周期launch_app启动 TextEdit,pgrep -n TextEdit拿到 PID 后kill_app回收;若拿不到 PID 则直接把kill_app记为 FAIL。
  6. group 4:per-window 状态。对真实解析出的window_id调用get_window_statecapture_mode: tree)、get_accessibility_treezoom(200x200 区域);窗口号解析失败时这三个工具统一记 SKIP。
  7. group 5:输入合成move_cursor之后对 harness 窗口做click/double_click/right_click/dragdelivery_mode: foreground)/scroll/type_text/press_key/hotkey["cmd","a"])/bring_to_front——注释说明这些坐标点击即便 AX 目标不精确也会走通 CGEvent 路径;set_value因缺少element_index(需要快照才能取得)记 SKIP,注明改由harness_appkit_text_input集成测试覆盖。
  8. group 6:别名与特殊项type_text_chars有意不注册进工具注册表的废弃别名,由 mcp-server 的 invoke 层解析为type_text,故记 SKIP;page(需要带--remote-debugging-port的 Chromium)与replay_trajectory(需要已录制轨迹文件)同样记 SKIP。

判定逻辑:PASS / FAIL / SKIP 的精确口径

分类核心在run_tool函数(macos.sh L39-L65),口径值得逐条记住:

  • SKIP:输出中匹配unsupported_on_platformis Windows-onlyis Linux-onlyis macOS-only——即"该工具在本平台是有意为之的跨平台 stub",说明调用正确但在此 OS 上无意义,不算 FAIL;
  • PASS:退出码 0输出既不以开头、也不以Error:开头;
  • FAIL:退出码非 0(记录exit=<code>与首行前 100 字符),或退出码 0 但输出带错误标记(记录为exit0+❌);
  • 无参数工具的 JSON 参数默认为{},且注释专门解释了为什么不写 bash 惯用法${2:-{}}:bash 会把它解析为${2:-{}'加字面},结果得到{而非{},破坏下游 JSON 解析——这是作者在 Linux 版脚本中踩过的同一个坑。

汇总阶段(macos.sh L198-L218)用 awk 保留每个工具最后一次的判定(后写的record()覆盖先写的),按工具名排序输出对齐表格,再统计Tools probed / PASS / FAIL / SKIP,最后以[[ "$fail" -eq 0 ]]作为脚本退出条件——即任何 FAIL 都会让 runner 以非零码退出,可直接挂进 CI。

两个工程细节值得一提:脚本顶部只set -u而不开set -e,因为冒烟测试的预期就是"允许个别工具失败但继续扫完";结果行以TOOL|VERDICT|REASON写入mktemp临时文件,且注释明确说明这是因为 macOS 自带 bash 3.2 没有关联数组,只能以换行分隔的行记录、最后排序去重。

基线 diff:用结果文件捕获覆盖度回归

smoke README 定义了第二个核心机制:每个脚本会为当前驱动版本results/子目录下检入一份基线结果文件(如results/macos.txt),用于对比捕获工具覆盖度的回归:

./macos.sh > /tmp/run.txt diff results/macos.txt /tmp/run.txt

需要说明的是,就当前仓库快照而言,smoke/目录下实际提交的只有 README.md 与 macos.sh,基线文件按上述约定在首次运行后生成并提交即可生效。这套 diff 工作流的意义在于:冒烟测试不追求断言每个工具的返回内容,只追求工具面的行为稳定性——某个工具从 PASS 变 FAIL、或某个原本 SKIP 的平台 stub 突然报错,都会在 diff 中立刻显形。

与 Rust 集成测试的衔接:fixture 消费链

smoke runner 是同一 fixture 体系里最"宽"的一层,其上下游都在 Rust 集成测试说明中有明确定位:

  • 测试按前缀命名分层:protocol_*_test.rssession_capture_scope_test.rsschema_*_test.rs默认运行(headless),harness_<toolkit>_test.rsdesktop_scope_<os>_test.rs标记#[ignore],需要暂存的 harness 应用与真实交互式桌面;
  • 跨平台规范矩阵是cross_platform_behavior_test.rs,对 Electron / Tauri(以及 macOS 上的 WKWebView)运行相同的外部状态场景,每行在cases.jsonl中声明动作、AX/PX 定位方式、前台/后台投递、作用域与外部 oracle,观察结果写入results.jsonl,Rust reporter 校验两份文件并渲染summary.md
  • CI / VM runner 通过环境变量CUA_TEST_DRIVER_BINCUA_TEST_APPS_ROOTCUA_TEST_WORKSPACE_ROOT指向工作区外的构建产物,并设置CUA_TEST_REQUIRE_FIXTURES=1把"fixture 缺失"从静默 SKIP 变为硬失败;
  • 规范化的 OS 级 E2E 入口另有其位:macOS 为libs/cua-driver/tests/runners/macos-lume/run-all.sh(内部委托 scripts/ci/macos/run-rust-e2e.sh,后者会先调用tests/fixtures/build/macos.sh构建 fixture),Linux 为 scripts/ci/linux/run-rust-e2e.sh,Windows 为scripts/ci/windows/run-rust-e2e.ps1 -RequireGui

因此三者形成清晰的金字塔:Rust 集成测试做行为级精确断言(MCP stdio 路径),CLI smoke runner做工具面级广覆盖(CLI 解析路径),基线 diff把后者的输出钉成可回归对比的资产。fixture 维护规则(见 fixture README 的 Maintenance Rules)也呼应了这一设计:新共享 ID 必须先加入shared/scenarios.json才能在测试中断言;行为证据统一通过 Rust testkit 与规范 OS runner 记录,"不要添加第二套 Python 或 shell 断言层"——smoke runner 正是被允许的例外之一,因为它验证的是 CLI 入口这条独立代码路径而非断言 UI 状态。

小结

smoke README 用不到三十行定义了一套完整的跨 OS 验证策略,其要点可以浓缩为四条:

  1. 路径互补:CLI 冒烟与 MCP 集成测试分别覆盖"工具寻址与退出行为"和"UIA/AX 状态断言",互不替代;
  2. 三态口径:PASS = 退出码 0 且无错误标记;FAIL = 非零退出或带错误标记的输出;SKIP = 有意的跨平台 stub 或缺 fixture,且在汇总表中给出理由;
  3. 快速全扫:单个 runner 约 30 秒遍历全部注册工具,FAIL 数非零即非零退出,可直接入 CI;
  4. 基线 diffresults/下的版本化基线文件让工具面行为漂移变成一行diff可查的回归信号。

如需继续深入,可从 macos.sh 的run_tool判定实现、cli.rs 的call子命令解析,以及 Rust 集成测试目录说明 中的测试分层与环境变量约定三个文件入手。

【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 5:33:01

Spring注解开发核心原理与最佳实践

1. Spring注解开发概述Spring框架自2003年诞生以来&#xff0c;已经成为Java企业级开发的事实标准。而注解(Annotation)作为Java 5引入的重要特性&#xff0c;在Spring 3.0版本后逐渐成为配置的主流方式。注解开发模式通过将配置信息直接嵌入到代码中&#xff0c;极大地简化了传…

作者头像 李华
网站建设 2026/9/13 5:30:02

15分钟跑通DataHub元数据管理:3个由浅入深的定制配方

15分钟跑通DataHub元数据管理&#xff1a;3个由浅入深的定制配方 【免费下载链接】datahub The Context Platform for your Data and AI Stack 项目地址: https://gitcode.com/GitHub_Trending/da/datahub 周四下午产品来催&#xff1a;周五前要把 Snowflake 里所有表的…

作者头像 李华
网站建设 2026/9/13 5:28:33

Budibase 开发环境在平台更新后出现不兼容问题时如何重置恢复

Budibase 开发环境在平台更新后出现不兼容问题时如何重置恢复 【免费下载链接】budibase AI agents, automations and apps that run your operations. Model agnostic. 项目地址: https://gitcode.com/GitHub_Trending/bu/budibase 如果你在本地开发 Budibase&#xff…

作者头像 李华
网站建设 2026/9/13 5:27:23

国产DSP开发板FCP32C335深度实测与工程落地指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华