拓冰建站拓冰建站
首页 / 资讯中心 / 正文

PowerToys UI 自动化测试框架实战指南:`.Next`/winappcli 新体系、持久化本地 VM 与 CI 流水线全流程

PowerToys UI 自动化测试框架实战指南.Next/winappcli 新体系、持久化本地 VM 与 CI 流水线全流程【免费下载链接】PowerToysMicrosoft PowerToys is a collection of utilities that supercharge productivity and customization on Windows项目地址: https://gitcode.com/GitHub_Trending/po/PowerToys本文以 PowerToys 仓库的 UI 测试框架开发文档 为主线系统讲解其两代 UI 自动化测试体系新一代Microsoft.PowerToys.UITest.Next基于winappcli驱动 Windows UI Automation与旧版 WinAppDriver/Selenium 框架涵盖本地运行、持久化 Hyper-V 虚拟机验证、CI 流水线参数以及如何为一个模块编写第一批 UI 测试。读完本文你将掌握.Next测试工程从搭建、编译、单测调试到双系统Windows 10 / Windows 11全量绿灯的完整实操链路。框架总览两代 UI 测试体系如何并存PowerToys 为模块和 Settings 提供两套 UI 测试框架当前共存于仓库中Microsoft.PowerToys.UITest.Next新推荐通过winappcliwinapp.exe驱动 Windows UI Automation编译为 Microsoft.Testing.Platform 可执行程序。其基础类与公共 API 位于 src/common/UITestAutomation.Next包括UITestBase、Session、By、WindowControl、WaitHelper、VisualAssert等工程文件为 UITestAutomation.Next.csproj。新测试一律使用该框架。Microsoft.PowerToys.UITest旧基于 WinAppDriver Selenium位于 src/common/UITestAutomation。文档声明它仅保留给既有测试套件与迁移基线参考不要用它作为新.Next工程起点。两者关键差异可以从 UITestBase.cs 的类注释中直接印证维度.Next新体系旧版体系驱动引擎winappcli每个 UI 调用 shell 出子进程winapp.exe并解析其 JSONWinAppDriver 服务默认127.0.0.1:4723 Selenium/Appium运行时形态Microsoft.Testing.Platform 可执行程序.exe直接运行并产出 TRXMSTest DLL经 Test Explorer /vstest.console.exe执行依赖除 MSTest 外无第三方 NuGet 依赖Selenium/Appium 相关包选择器无 XPath/CssSelector采用By与 winappcli 选择器语法支持 XPath 等 Selenium 惯用法元素模型无状态元素stateless每次操作即时解析有状态WindowsElement从源码注释可确认.Next基础类刻意保持与旧版相同的“外观形态”——继承同一个命名风格的UITestBase在测试中继续使用Session/FindT以便迁移大部分工作是机械化的 API 映射而非重写。仓库中已有多个.Next参考工程例如 FancyZones.UITests.Next、Peek.UITests.Next、PowerRename.UITests.Next 与 ScreenRuler.UITests.Next。Agent 辅助工作流两个仓库 Skill 覆盖“实现—验证”闭环文档明确了两个配套的仓库级 Skill覆盖 UI 测试从创建到在真实桌面验证的完整循环UI-tests migration skill负责创建新的.Next测试工程、移植旧版 WinAppDriver 测试、设计稳定的选择器/等待/生命周期并为 CI 准备测试。该 Skill 按场景区分两种工作流场景 A移植——已存在旧版[Module].UITests工程时新建并列的[Module].UITests.Next工程做 1:1 重实现场景 B从零——模块没有任何 UI 测试、但有真人验收清单 markdown 时新建[Module].UITests工程并把每条清单转成自动化用例。Local-VM UI-tests skill负责创建可持久化的 Windows 10 与 Windows 11 Hyper-V 客户机暂存当前构建/测试产物在标准用户交互桌面中执行测试并收集可持久化的 TRX/日志/截图/视频证据。对于新写或迁移的测试两个 Skill 应配合使用先在宿主机编译通过再把本地 VM 作为默认的“活体 agentic 循环”——先跑一个确定性测试、诊断并修复最后才在两种受支持的 Windows 版本上扩展到完整模块套件。VM 会暴露首次运行、profile、Explorer、WebView2、前台窗口与进程生命周期等假设且不会污染宿主 profile。模块特有的约束记录在各模块的开发文档中。例如文档专门指出 PowerRename 的 UI 测试涉及命令行选择、Boost 引擎生命周期与已签名 shell 扩展要求详见 doc/devdocs/modules/powerrename.md 的 UI 测试说明ScreenRuler 的说明见 doc/devdocs/modules/screenruler.md。运行前准备.Next测试前置条件构建产物编译 PowerToys 运行时与.UITests.Next测试可执行程序。安装固定版本的winappcli可以安装官方 pin 定的运行时版本或设置环境变量WINAPP_CLI_PATH指向winapp.exe流水线辅助脚本为 .pipelines/InstallWinAppCli.ps1。迁移 Skill 中提到其安装命令为winget install Microsoft.winappcli。注意.Next工程只在运行期需要winapp.exe编译期零托管依赖因此没有安装 winappcli 也能做编译验证。使用真实交互桌面UIA、前台输入、Explorer、热键与渲染在 session 0 中都无法工作——无头环境跑不了 UI 测试。退出已运行的 PowerToys 实例宿主桌面运行时harness 拥有 runner 与模块生命周期的控制权测试会自行拉起PowerToys.exe如--open-settings旧实例会干扰启动与前台切换。这一“harness 拥有生命周期”的约束可在 UITestBase.cs 源码中得到印证基类内置StaleProcessNames默认含PowerToys、PowerToys.Settings、PowerToys.FancyZonesEditor每个测试前会先杀掉残留进程保证从干净桌面状态启动默认每次测试都是“独立启动 拆除”只有子类将ReuseScopeAcrossTests置为true时才按类复用同一窗口。旧版Legacy测试前置条件安装 Windows Application Driverv1.2.1到默认目录C:\Program Files (x86)\Windows Application Driver。在 Windows 设置中启用开发人员模式Developer Mode。运行测试运行.Next测试用仓库构建脚本编译目标工程然后直接运行产出的 Microsoft.Testing.Platform 可执行程序tools\build\build.cmd -Path src\modules\Module\Tests\Module.UITests.Next -Platform x64 -Configuration Debug $exe x64\Debug\tests\Module.UITests.Next\net10.0-windows10.0.26100.0\Module.UITests.Next.exe $exe --filter TestCategoryModule --report-trx --report-trx-filename module.trx --results-directory .\TestResults\Module --timeout 7m几个参数要点过滤器应使用显式过滤属性如Name、Name~、FullyQualifiedName~或TestCategory。裸的显示名可能选中 0 个测试。超时上面的7m只是聚焦过滤示例模块级或工程级全量运行请调大超时值。若编译失败可查看工程旁的build.Configuration.Platform.errors.log。从迁移 Skill 的说明可知当依赖图中包含UITestAutomation.Next的 COM 引用时不要用裸dotnet build.NET SDK MSBuild 无法执行ResolveComReference会报 MSB4803应使用仓库构建脚本或 Visual Studio 的全框架 MSBuilddotnet restore仅用于首次生成project.assets.json。另外.Next测试不需要提升权限新 harness 以非提升方式启动 runner这与旧版旧 harness 以runas提升方式启动 PowerToys不同。运行旧版测试如果 PowerToys 正在运行先退出。在 Visual Studio 中打开PowerToys.slnx并构建解决方案。在Test Explorer中运行测试菜单Test Test Explorer或快捷键CtrlE, T。迁移 Skill 特别提醒旧版套件若要命令行/CI 基线运行需要以管理员身份先启动WinAppDriver.exe再用vstest.console.exe执行旧 harness 通过ProcessStartInfo { Verb runas }提升启动 PowerToys非提升的测试宿主会在启动阶段以误导性的Win32Exception级联全部失败。在持久化本地 VM 中运行.Next测试文档推荐的本地执行后端是一对通过PowerShell Direct驱动的持久化 Hyper-V 客户机Windows 10 与 Windows 11每台都有已登录的标准用户桌面。VM 能暴露首次运行、profile、Explorer、WebView2、前台与生命周期假设同时保留已暂存产物以便快速“编辑→构建→重跑”。一次性宿主设置在仓库外建一个 VM 根目录然后按生成的后续步骤创建不入库的配置pwsh .github\skills\ui-tests-local-vm\scripts\Initialize-LocalVm.ps1 -DestinationRoot C:\PowerToysUiTestVm pwsh .github\skills\ui-tests-local-vm\scripts\Initialize-LocalVmHost.ps1 -VmRoot C:\PowerToysUiTestVm -CheckOnly如果-CheckOnly报告IsReadyfalse必须由人类运行它打印出的提权命令——Hyper-V 组成员身份、受 DPAPI 保护的客户机管理员凭据以及客户机创建都无法由 Agent 自动完成。完整过程参见 setup 参考文档其中包含安装介质获取、vm.config.psd1编写、Windows 10/11 客户机创建与基线检查点checkpoint建立。运行 Agentic 循环先准备一个模块交换目录module exchange内含ui-tests.zip、powertoys-runtime.zip、winappcli.zip与dotnet-runtime.zip四个压缩包具体打包规则见 agentic-loop 参考文档。产物会被解压到客户机本地存储测试从不直接从宿主共享盘执行。$vmRoot C:\PowerToysUiTestVm $exchange $vmRoot\shared\PowerToysUiTests\Module pwsh .github\skills\ui-tests-local-vm\scripts\Invoke-LocalVmUiTest.ps1 -VmName PowerToysUiTest-Win11 -ConfigurationPath $vmRoot\vm.config.psd1 -VmRoot $vmRoot -ExchangeRoot $exchange -TestExecutable Module.UITests.Next.exe -Filter NameModule.FocusedTest -Platform x64Win11 -BuildLabel (git rev-parse HEAD) -SuiteTimeout 15m -TimeoutMinutes 25 -ReuseStagedPayload控制器会按需启动客户机验证标准用户 token、Explorer 会话与桌面尺寸再通过受限的交互式计划任务运行测试持续流式输出进度最终返回status.json、TRX 计数、逐测试失败信息、日志、截图以及保留的失败录像全部落在ExchangeRoot\LocalVmResults\runId下。迭代节奏务必遵守每次源码变更后只重建并替换发生变化的压缩包然后用相同的聚焦过滤器配合-ReuseStagedPayload重跑待该行为被充分理解后再逐步放宽范围。一个模块只有在 Windows 10 与 Windows 11 上**全量类别过滤器都通过executed total**才算完成。最终做“干净 profile”确认前应恢复基线检查点Reset-LocalVm.ps1 -Restore。桌面、PowerShell Direct、payload、shell 扩展签名与证据导出等问题参见 本地 VM 故障排查指南。相关资源约定也值得注意默认资源档为 4 vCPU/8 GB RAM套件全绿后再考虑降为Constrained档1 vCPU/4 GB-Platform参数并非装饰——它会以platform环境变量传入客户机、参与视觉基线命名只允许x64Win10、x64Win11或ARM64三种取值Windows on ARM 宿主只能跑 Windows 11 ARM64 客户机。在 CI 流水线中运行测试PowerToys 的 UI 测试流水线提供灵活的构建与测试选项Pipeline 参数buildSource选择测试用的构建来源。latestMainOfficialBuild下载并使用 main 分支最新的官方 PowerToys 构建默认值buildNow基于当前源码现场构建 PowerToys 并用于测试specificBuildId通过specificBuildId参数指定的构建 ID 下载特定构建。specificBuildId当buildSource specificBuildId时填写要下载并测试的确切构建 ID。默认值为占位符xxxx。适用场景针对特定已知构建做可复现测试、针对某一构建版本做回归验证、发布前在特定构建上验证修复。用法是填入构建 ID 数字如12345。uiTestModules指定要构建与运行的 UI 测试模块。该参数同时控制要构建的.csproj工程与要执行的.dll测试程序集。示例[UITests-FancyZones]——只跑 FancyZones UI 测试[MouseUtils.UITests]——只跑 MouseUtils UI 测试[UITests-FancyZones, MouseUtils.UITests]——同时跑多个指定模块留空则构建并运行全部 UI 测试模块。重要uiTestModules的取值必须同时匹配测试工程名构建期.csproj选择与测试程序集名执行期.dll运行。构建模式官方构建测试buildSource latestMainOfficialBuild或specificBuildId下载并安装官方 PowerToys 构建main 最新版或指定构建 ID只构建 UI 测试工程全部或按uiTestModules选取对已安装的 PowerToys 运行 UI 测试自动同时测试机器级与每用户安装模式。当前源码构建测试buildSource buildNow从当前源码构建整个 PowerToys 解决方案构建 UI 测试工程全部或按uiTestModules选取对刚构建的 PowerToys 运行 UI 测试使用当前流水线构建的产物。所有模式都支持uiTestModules参数来控制具体构建与运行的模块使用官方构建时机器级与每用户安装模式会被自动测试。为模块添加第一批 UI 测试新工程一律走迁移 Skill无论是新写.Next工程还是移植旧用例都应使用 UI-tests migration skill——其中包含当前的可执行工程脚手架、API 映射、命名规则、CI 稳定性清单与已验证的示例工程。建议按顺序阅读它的 framework-differences新旧框架概念差异、api-mapping逐行 API 对照表、project-setupcsproj 脚手架与工程放置/命名规则、patterns-and-pitfalls常见模式与陷阱以及 ci-stabilityCI 稳定性要点与预检清单等参考文档。工程命名约定测试工程统一放在模块的Tests子目录下命名格式为{ModuleFolder}/Tests/{ModuleName}-{TestType(Fuzz/UI/Unit)}Tests。.Next工程按“场景 A”规则命名为[Module].UITests.Next并与旧工程并列共存而不是删除旧工程。下图展示了仓库内 UI 测试工程的目录组织形态旧版工程的工程文件模板仅存量套件参考下面这个工程文件样例描述的是旧版 WinAppDriver 框架仅保留给既有旧套件使用新.Next工程请勿照抄.Next模板在迁移 Skill 的templates/Module.UITests.Next.csproj特征是OutputTypeExe、TargetFrameworknet10.0-windows10.0.26100.0、IsTestingPlatformApplication、RunVSTestfalse且只ProjectReference到UITestAutomation.Next.csproj。Project SdkMicrosoft.NET.Sdk !-- Look at Directory.Build.props in root for common stuff as well -- Import Project..\..\..\Common.Dotnet.CsWinRT.props / PropertyGroup ProjectGuid{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0}/ProjectGuid RootNamespacePowerToys.Hosts.UITests/RootNamespace AssemblyNamePowerToys.Hosts.UITests/AssemblyName IsPackablefalse/IsPackable IsTestProjecttrue/IsTestProject Nullableenable/Nullable OutputTypeLibrary/OutputType !-- This is a UI test, so dont run as part of MSBuild -- RunVSTestfalse/RunVSTest /PropertyGroup PropertyGroup OutputPath$(SolutionDir)$(Platform)\$(Configuration)\tests\Hosts.UITests\/OutputPath /PropertyGroup ItemGroup PackageReference IncludeMSTest / ProjectReference Include..\..\..\common\UITestAutomation\UITestAutomation.csproj / /ItemGroup /Project注意将OutputPath改为自己模块的路径。编写测试类继承 UITestBase 并指定 Scope测试类继承自UITestBase。默认 Scope 从 PowerToys 设置界面开始如果要从自己的模块窗口开始就在构造函数中指定模块与窗口尺寸[TestClass] public class HostModuleTests : UITestBase { public HostModuleTests() : base(PowerToysModule.Hosts, WindowSize.Small_Vertical) { } }在.Next框架中这个构造函数签名与UITestBase保持一致基类构造函数接受scope默认PowerToysModule.PowerToysSettings、size可选固定窗口尺寸与enableModules非 null 时会在启动 runner 前把全局settings.json精确配置为只启用这些模块形成确定性的模块基线三个参数。然后就可以开始执行 UI 操作例如[TestMethod(Hosts.Basic.EmptyViewShouldWork)] [TestCategory(Hosts File Editor #4)] public void TestEmptyView() { this.CloseWarningDialog(); this.RemoveAllEntries(); // Add an entry button (only show-up when list is empty) should be visible Assert.IsTrue(this.HasOneHyperlinkButton(Add an entry), Add an entry button should be visible in the empty view); VisualAssert.AreEqual(this.TestContext, this.Find(Entries), EmptyView); // Click Add an entry from empty-view for adding Host override rule this.FindHyperlinkButton(Add an entry).Click(); this.AddEntry(192.168.0.1, localhost, false, false); // Should have one row now and not more empty view Assert.IsTrue(this.HasButton(Delete), Should have one row now); Assert.IsFalse(this.HasHyperlinkButton(Add an entry), Add an entry button should be invisible if not empty view); VisualAssert.AreEqual(this.TestContext, this.Find(Entries), NonEmptyView); }从这段示例可以看出 UI 测试的通用骨架先用可见性断言确认空视图状态用VisualAssert.AreEqual对Entries元素做视觉基线比对再通过元素查找与Click()驱动交互最后用正/反断言验证状态迁移。.Next的VisualAssert支持把“WinUI/WebView 组合内容”纳入视觉基线ScreenRecording会在失败时保留桌面录像与截图方便事后诊断。辅助工具与设计要点可访问性工具编写测试时需要查看元素的 accessibility 数据例如确认某个按钮的可达名称来定位点击目标。Windows 上的Accessibility Insights是官方推荐的检查工具可查看 UIA 树、元素属性与 AutomationId。选择器设计新框架使用By与 winappcli 选择器语法无 XPath/CssSelector且元素为无状态——每次操作即时解析多窗口发现通过Session的作用域窗口级 vs 进程级如Session.FromProcess完成。可寻址性兜底若某个控件如图标按钮只有 tooltip 标签、没有 UIA Name迁移 Skill 允许的唯一产品侧改动是给它添加AutomationProperties.AutomationId禁止使用x:Name也禁止更大的隐藏 peer/状态字符串等改动。稳定性优先优先使用“权威信号 等待”而不是固定 sleep交互前做前台/完整性校验失败证据截图/视频先于一切结论查看——断言只能告诉你“找到 0 行”截图才能告诉你列表确实是空的还是选择器写错了。总结一条从“写测试”到“全绿发布”的完整链路把文档与两个 Skill 串起来PowerToys UI 测试的标准推进路径是① 用迁移 Skill 搭建.Next工程并按稳定性清单写测试 → ② 宿主机构建到 exit code 0 → ③ 在本地 VM先 Win10 后 Win11跑一个确定性测试并诊断 → ④ 修复后以-ReuseStagedPayload增量重跑、逐步放宽 → ⑤ 两套系统全量executed total→ ⑥ 恢复基线检查点做干净 profile 终验 → ⑦ 提交 CI用buildSourceuiTestModules参数控制官方构建或现场构建的流水线验证。理解.Next的 winappcli 引擎模型、生命周期归属harness 拥有 runner 与模块生命周期以及“测试必须在真实交互桌面运行”这三个前提是避免大部分“本地绿、CI 红”循环的关键。【免费下载链接】PowerToysMicrosoft PowerToys is a collection of utilities that supercharge productivity and customization on Windows项目地址: https://gitcode.com/GitHub_Trending/po/PowerToys创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门