qwen-code cua-driver Windows Rust Runner 实战指南:在 RDP/交互式桌面会话中驱动 Windows GUI 测试矩阵
【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code
本篇指南围绕 qwen-code 仓库中packages/cua-driver的 Windows Rust harness runner 展开,讲解如何通过tests/runners/windows/run-all.ps1在 Azure RDP 或交互式 scheduled-task 验证环境中构建仓库内 Windows fixtures、运行 Rust 单元测试与 typed harness 矩阵,并正确处理 Session 0、GUI 会话锁定与可选外部应用套件的取舍。读完本文,你将掌握该 runner 的完整运行链路、参数语义、fixtures 构建方式,以及从桌面状态诊断到 CI 强制的全套 Windows GUI 验证方法论。
一、Windows Rust Runner 是什么:一句话定位
在 qwen-code 的packages/cua-driver测试体系中,tests/runners/windows/README.md所描述的是Windows 平台的 Rust harness 运行器(runner)。它服务于一个明确的前提:cua-driver 需要验证的是“真实交互式用户桌面”上的 GUI 行为(窗口激活、焦点保持、UIA/AX 树定位、桌面轨迹录制等),因此必须在RDP 会话或交互式控制台会话中运行,而不能在无头环境里假装完成。
该 runner 的核心职责(依据 tests/runners/windows/README.md)可以归纳为三点:
- 构建仓库本地(repo-local)的 Windows fixtures:即 WPF、WinUI3、WebView2、Electron、Tauri 等确定性宿主测试应用;
- 运行 Rust 单元测试与 typed harness 矩阵:包括
protocol_*、schema_*、harness_<toolkit>_*、desktop_scope_windows_*等分类; - 有意跳过可选外部应用套件:例如 LibreOffice,因为这类套件依赖环境镜像中额外安装的软件,不属于仓库内 fixtures 的可复现范围。
二、如何运行:两条入口命令与参数语义
原文档给出了最核心的用法。在packages/cua-driver目录下、且处于RDP 或控制台(console)会话中执行:
# 基础运行:构建 fixtures 并跑完整 Rust harness 矩阵 .\tests\runners\windows\run-all.ps1 # 强制校验 GUI 桌面可用:把桌面不可用的自跳过升级为硬失败 .\tests\runners\windows\run-all.ps1 -RequireGui-RequireGui开关的深层含义需要结合源码理解。查看 run-all.ps1 的实现可以发现,该脚本本体非常薄,它是所有平台 runner 的统一“门面”:
param( [switch]$NoBuild, # 跳过 fixtures 构建(复用上一次的构建产物) [switch]$RequireGui # 要求真实可用的 GUI 桌面,否则失败 ) Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" $repoRoot = Resolve-Path (Join-Path $PSScriptRoot "..\..\..\..\..") $canonicalRunner = Join-Path $repoRoot "scripts\ci\windows\run-rust-e2e.ps1" if (-not (Test-Path $canonicalRunner)) { throw "Canonical Windows E2E runner not found: $canonicalRunner" } & $canonicalRunner -NoBuild:$NoBuild -RequireGui:$RequireGui exit $LASTEXITCODE关键信息有两点:
- 调用链:
run-all.ps1本身不做测试执行,它定位仓库根目录(从$PSScriptRoot向上回溯五级),并委派给仓库级规范入口scripts/ci/windows/run-rust-e2e.ps1,最后以exit $LASTEXITCODE透传退出码,保证 CI 能正确捕获失败; - 参数透传:
-NoBuild与-RequireGui原样透传。-RequireGui的作用在 Rust 侧由环境变量CUA_REQUIRE_GUI承接——在专用 GUI 运行器上设置CUA_REQUIRE_GUI=1,即可把桌面自跳过(self-skip)变成硬失败,并输出完整的桌面状态诊断(见 Rust 集成测试 README)。
注意:虽然
run-all.ps1是文档推荐的面向 RDP/console 会话的入口,但在当前仓库快照中scripts/ci/windows/run-rust-e2e.ps1并未随库检出(仓库只读且不包含该 CI 目录),因此实际可查看、可验证的入口即为tests/runners/windows/run-all.ps1本身及其上层测试文档。文章其余部分以仓库内已确认存在的源码与文档为事实依据。
三、为什么必须用 RDP / 交互式 scheduled task:Session 0 与桌面可达性
Windows Rust Runner 最容易被忽略、也最容易踩坑的是运行环境约束。这不是跑一个普通命令行测试,而是要在“有人登录、桌面解锁”的交互式会话中驱动真实 GUI。仓库的 Rust 集成测试 README 明确警告:
Windows GUI tests require a usable interactive desktop. SSH-launched commands start in Session 0 and cannot drive the user's desktop directly; launch GUI tests through an interactive scheduled task (
/IT) or equivalent so they run in the logged-on user session.
这句话背后的 Windows 会话模型是:SSH 启动的命令默认运行在 Session 0(服务会话),无法直接驱动已登录用户的桌面(窗口不显示、UIA 树不可达、截图与鼠标注入都会失败)。因此正确的启动方式是:
- 通过RDP登录到目标 GUI VM,在 RDP 会话内直接运行 runner;或
- 通过交互式 scheduled task(
/IT标志)让任务在已登录的用户会话中执行,等价于把测试进程放进真实桌面。
如果当前输入桌面不是Default或无法打开,通常意味着会话被锁定或断开。文档给出的处置手段是(见 Rust 集成测试 README):
- 重新连接 RDP;
- 在一次性 GUI VM 上使用
tscon /dest:console将会话切换到控制台; - 或者将 VM 启动到未锁定的控制台会话后再运行被
#[ignore]标记的 GUI 测试。
此外,testkit 的原生DesktopObserver会记录前景窗口、Z 序、光标与泄漏输入状态,用于断言“承诺无桌面副作用”的行(row)。这正是-RequireGui/CUA_REQUIRE_GUI=1的用武之地——它把这些桌面自跳过变成硬失败,防止 CI 在不可用的桌面上“假绿”。
四、Runner 到底跑什么:Windows harness 矩阵与测试命名约定
进入packages/cua-driver后,Rust 侧测试位于 packages/cua-driver/rust/crates/cua-driver/tests/。命名约定决定了哪些测试默认执行、哪些需要 GUI 环境:
| 测试前缀 | 默认执行 | 目的 |
|---|---|---|
protocol_*_test.rs | 是 | MCP/CLI 协议与 schema 行为 |
session_capture_scope_test.rs | 是 | 每会话策略隔离、升级、生命周期与废弃配置键 |
schema_*_test.rs | 是 | 生成 schema 的一致性 |
harness_<toolkit>_test.rs | 否,标记#[ignore] | 特定 toolkit 的 harness 应用 |
desktop_scope_<os>_test.rs | 否,标记#[ignore] | 平台窗口/桌面作用域契约 |
也就是说,Windows Rust Runner 跑的核心就是这些默认不跑的#[ignore]GUI 测试——通过run-all.ps1这类规范入口在真实桌面上以带--ignored的方式执行。Windows 平台对应的主要是:
harness_wpf_test.rs、harness_winui3_test.rs、harness_webview_test.rs等 toolkit 专属用例;desktop_scope_windows_test.rs平台窗口/桌面作用域契约;cross_platform_behavior_test.rs:跨平台行为矩阵,对 Electron 与 Tauri 运行相同的外部状态场景(Windows 上对应 UIA 表面),其矩阵行(action、AX/PX 定位、前台/后台投递、作用域、driver 路由、外部 oracle、期望行为)声明在cases.jsonl,观察结果与派生状态记录在results.jsonl,Rust reporter 校验两者并渲染summary.md。
同时,仓库级 runner 会设置CUA_E2E_RECORDINGS_ROOT,让每个 testkitMcpDriver把完整桌面轨迹录制到独立目录,包含recording.mp4、光标采样、action JSON、每轮截图与trajectory.json测试标签清单。Windows 上需要 FFmpeg,runner 会用ffprobe校验每个 MP4 后才报告成功,另有 Rust 预检在行为用例运行前一次性验证桌面、fixture、AX 树、截图与视频生命周期。
五、fixtures 从哪来:构建仓库内 Windows 测试应用
Runner “构建 repo-local Windows fixtures”的含义,详见 tests/fixtures/README.md:fixtures 是**源码优先(source-first)**的确定性宿主应用,构建脚本会把产物 stage 到packages/cua-driver/rust/test-apps/harness-<name>/,二进制不提交进仓库。
Windows 侧的 fixture 应用位于 tests/fixtures/apps/windows/:
| Harness | 源码位置 | Staged 输出 | 主要测试表面 |
|---|---|---|---|
| WPF | apps/windows/wpf | harness-wpf | UIA/WPF 控件 |
| WinUI3 | apps/windows/winui3 | harness-winui3 | UIA/XAML 控件 |
| WebView2 | apps/windows/webview2 | harness-webview | Chromium web UIA |
| Electron | apps/cross-platform/electron | harness-electron | Chromium web AX/UIA/AT-SPI |
| Tauri | apps/cross-platform/tauri | harness-tauri | native webview AX/UIA/AT-SPI |
构建命令(在packages/cua-driver/tests/fixtures下):
# 全量构建:WPF、WinUI3、WebView2、Electron、Tauri .\build\windows.ps1 # 跳过某个 toolkit .\build\windows.ps1 -Skip winui3Windows 宿主要求:.NET 8 SDK、Node.js/npm(Electron)、Rust(Tauri)。共享的shared/scenarios.json是所有 AutomationId、AX 标识符、期望窗口标题与 fixture 名的唯一事实来源;webview 类 harness 会加载共享的shared/web/index.html。这意味着 runner 构建出的每个 fixture 都符合同一套共享场景契约,测试矩阵无需为各 toolkit 各写一套断言基线。
六、为什么跳过 LibreOffice:可选外部应用套件的边界
原文档特别强调 runner“intentionally skips optional external-app suites such as LibreOffice”。这类套件的定位在 Rust 集成测试 README 中有完整说明:它们是针对真实已安装应用的 Rust 源码级覆盖,但不属于规范 run-all 路径,因为它们依赖仓库内 fixtures 之外的软件或桌面状态:
harness_libreoffice_test.rs:Windows LibreOffice Writer/Calc,需要安装 LibreOffice,或通过LO_SWRITER_EXE/LO_SCALC_EXE指向可执行文件;installed_app_launch_macos_test.rs/installed_app_textedit_macos_test.rs:macOS 专属;standalone_browser_behavior_test.rs:已安装 Chrome/Edge 的浏览器工具用例,需通过跨平台脚本单独跑。
从设计上看,这是一个可复现性与覆盖面的明确取舍:仓库内 fixtures 保证任何干净环境都能复现结果,而外部应用套件保留源码级事实来源、但按需在配好软件的环境上运行,二者互不污染。这也是run-all.ps1有意只走 repo-local fixtures 的原因。
七、与其他平台的呼应:Windows Runner 在跨平台体系中的位置
Windows Runner 并非孤岛,它与 macOS、Linux 运行器构成同一套跨平台验证方法论:
- macOS的规范入口是 tests/runners/macos-lume/run-all.sh,它要求已登录用户会话,并在委派给
scripts/ci/macos/run-rust-e2e.sh前校验已安装 driver 的 Accessibility 与 Screen Recording 授权; - Linux的仓库级入口是
scripts/ci/linux/run-rust-e2e.sh; - Windows即本文主题:
run-all.ps1→scripts/ci/windows/run-rust-e2e.ps1 -RequireGui。
三者共享同一套 fixtures(Electron/Tauri 跨平台 + 各平台原生 toolkit)、同一个cases.jsonl/results.jsonl/summary.md报告契约,以及同一个CUA_E2E_RECORDINGS_ROOT轨迹录制体系。跨平台矩阵的权威维护点在 docs/test-matrix.md,新增 harness、action、寻址模式、投递模式或操作系统相关的窗口系统用例时都要回写该矩阵。
此外,仓库还保留了Legacy Windows Sandbox路径(tests/runners/windows-sandbox/run-tests-in-sandbox.ps1),它会构建部分 Windows harness 应用并映射进沙箱。但正如 Rust 集成测试 README 所述,当前 Windows GUI 验证路径应使用通过 RDP 或交互式 scheduled task 启动的真实用户桌面会话,沙箱路径属于历史遗留。这正是-RequireGui存在的根本原因——GUI 测试必须见到真实桌面。
八、实战排查清单:让 Windows Runner 一次跑通
综合以上源码与文档,将常见故障与对策整理如下:
| 症状 | 根因 | 对策 |
|---|---|---|
| 所有 GUI 用例自跳过 | 会话锁定或断开,输入桌面不可用 | 重新连接 RDP;一次性 GUI VM 上执行tscon /dest:console;或将 VM 启动到未锁定控制台 |
| SSH 启动后窗口不可见 | 命令落在 Session 0 服务会话 | 改用 RDP 会话,或通过交互式 scheduled task(/IT)在已登录用户会话中运行 |
| CI 上“假绿” | 桌面不可用时被静默跳过 | 设置CUA_REQUIRE_GUI=1,配合-RequireGui将自跳过转为硬失败并输出桌面诊断 |
recording.mp4校验失败 | Windows 侧缺少 FFmpeg | 在环境镜像中安装 FFmpeg(runner 会以ffprobe校验视频) |
| fixtures 找不到 | 未构建或构建产物被清理 | 先运行tests/fixtures/build/windows.ps1(或保留-NoBuild缺省行为让 runner 自行构建),确认已安装 .NET 8 SDK、Node.js/npm、Rust |
| 需要复现外部应用行为 | LibreOffice 等不在 run-all 路径 | 安装对应软件并设置LO_SWRITER_EXE/LO_SCALC_EXE,按需运行harness_libreoffice_test.rs |
九、总结
packages/cua-driver/tests/runners/windows/README.md描述的是一个“小入口、大体系”的典型设计:run-all.ps1仅数十行,负责解析-NoBuild/-RequireGui并委派给仓库级 CI runner;真正的复杂度沉淀在 Rust 测试矩阵、source-first fixtures 构建与桌面会话管理之中。理解并善用这个 runner,等于掌握了在 Windows 上对 cua-driver 做真实桌面级 GUI 验证的标准姿势——从 RDP/交互式任务的启动约束,到CUA_REQUIRE_GUI的失败强制,再到 fixtures 的可复现边界,每一步都能在仓库源码与文档中找到对应依据。
如需深入,建议依次阅读 Rust 集成测试 README、fixtures README、test-matrix.md 与 test-harnesses-guide.md,它们共同构成了这条 Windows 验证链路的完整地图。
【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考