将桌面应用UI测试用例迁移至Azure虚拟机规模集遇WinAppDriver错误
尝试将桌面应用UI测试用例迁移至Azure虚拟机规模集,使用C# + WinAppDriver实现自动化,通过Azure DevOps流水线在远程服务器运行时触发以下错误:
Test method UserInterface.Test.UIAndConsoleTestCases.VerifyAllNames threw exception:
OpenQA.Selenium.WebDriverException: Failed to locate opened application window with appId: C:\Program Files\abc.exe, and processId: 5112
Stack Trace:
at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary2 parameters) at OpenQA.Selenium.Appium.AppiumDriver1.Execute(String driverCommandToExecute, Dictionary2 parameters) at OpenQA.Selenium.Remote.RemoteWebDriver.StartSession(ICapabilities desiredCapabilities) at OpenQA.Selenium.Remote.RemoteWebDriver..ctor(ICommandExecutor commandExecutor, ICapabilities desiredCapabilities) at OpenQA.Selenium.Appium.AppiumDriver1..ctor(ICommandExecutor commandExecutor, ICapabilities appiumOptions)
at OpenQA.Selenium.Appium.AppiumDriver1..ctor(Uri remoteAddress, ICapabilities appiumOptions, TimeSpan commandTimeout) at OpenQA.Selenium.Appium.Windows.WindowsDriver1..ctor(Uri remoteAddress, AppiumOptions AppiumOptions, TimeSpan commandTimeout)
at UserInterface.Test.CommonData.CreateNewSession(String InstalledPath) in D:\a\1\s\Projects\UITestcasesWinApp\UserInterface.Test\Helper\CommonData.cs:line 63
at UserInterface.Test.UIAndConsoleTestCases.VerifyAllFieldNamesAndTypes() in D:\a\1\s\Projects\UITestcasesWinApp\UserInterface.Test\UIAndConsoleTestCases.cs:line 267
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Standard Output Messages:
WinAppDriver started successfully!
Process ID: 432
Error: WaitForInputIdle failed. This could be because the process does not have a graphical interface.
HTTP/1.1 500 Internal Error
同时发现目标应用GRVU.exe运行时存在多个进程ID。
配置Azure VM的交互式会话
Azure DevOps流水线默认以无UI会话运行任务,WinAppDriver需要图形界面才能与桌面应用交互。需在流水线的虚拟机规模集任务中启用交互式登录,或者在VM上配置自动登录,确保桌面会话处于激活状态,避免WaitForInputIdle失败。放弃固定进程ID的窗口定位方式
应用多进程时,固定processId会导致定位错误。修改WinAppDriver的Capabilities配置:var appiumOptions = new AppiumOptions(); // 仅指定应用路径,不绑定固定进程ID appiumOptions.AddAdditionalCapability("app", "C:\\Program Files\\abc.exe"); // 若窗口标题固定,可通过窗口句柄定位(需先获取主窗口句柄) // appiumOptions.AddAdditionalCapability("appTopLevelWindow", 获取到的主窗口句柄); // 延长超时时间,给应用足够启动时间 var driver = new WindowsDriver<WindowsElement>(new Uri("http://127.0.0.1:4723"), appiumOptions, TimeSpan.FromSeconds(60));可通过Windows API(如
EnumWindows、FindWindow)枚举窗口,筛选出目标应用的主窗口句柄后再传递给WinAppDriver。优化应用启动与会话创建的时序
在启动应用后添加等待逻辑,确认主窗口完全加载后再创建WinAppDriver会话。例如检查进程的主窗口是否存在,或等待特定UI元素出现,避免因应用未完全启动导致的窗口定位失败。确保权限一致性
运行WinAppDriver和测试用例的账户需具备桌面交互权限,且与应用安装/运行的账户一致。建议使用有管理员权限的本地账户执行流水线任务,避免系统账户的权限限制。筛选应用主进程
若应用多进程是正常的子进程逻辑,可通过进程父ID筛选出主进程,再关联到对应的窗口,确保WinAppDriver连接的是承载UI的主进程窗口。
内容的提问来源于stack exchange,提问作者Anushka Singh

