【发布时间】:2022-06-24 04:39:16
【问题描述】:
我正在使用 C#、Appium 和 WinAppDriver 在桌面应用程序上自动执行 UI 测试,但是在启动 WPF 应用程序时我仍然遇到间歇性问题。我对此进行了大量研究,但找不到可靠的解决方案。
打开应用程序时会出现登录启动画面。输入正确的登录凭据后,应用程序打开前大约 5 秒会出现另一个加载启动屏幕。
我在打开应用程序时继续收到以下异常;它似乎是随机的。每次我认为我找到了一个模式时,我都会发现另一个与我认为我确定的模式相冲突的数据点。
例外
Message:
OpenQA.Selenium.WebDriverException : Failed to locate opened application window with appId: C:\Program Files (x86)\path to .exe\, and processId: 14124
Stack Trace:
RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
AppiumDriver`1.Execute(String driverCommandToExecute, Dictionary`2 parameters)
RemoteWebDriver.StartSession(ICapabilities desiredCapabilities)
RemoteWebDriver.ctor(ICommandExecutor commandExecutor, ICapabilities desiredCapabilities)
AppiumDriver`1.ctor(Uri remoteAddress, ICapabilities appiumOptions)
WindowsDriver`1.ctor(Uri remoteAddress, AppiumOptions AppiumOptions)
登录代码
if (session == null){
AppiumOptions appOptions = new AppiumOptions();
appOptions.AddAdditionalCapability("app", Path);
appOptions.AddAdditionalCapability("platformName", "Windows");
appOptions.AddAdditionalCapability("deviceName", "WindowsPC");
Thread.Sleep(TimeSpan.FromSeconds(5));
session = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), appOptions);
Assert.IsNotNull(session);
Thread.Sleep(TimeSpan.FromSeconds(10));
var allWindowHandles = session.WindowHandles;
session.SwitchTo().Window(allWindowHandles[0]);
session.Manage().Timeouts().ImplicitWait = TimeSpan.FromMinutes(1);
//Enter password and login
session.FindElementByAccessibilityId("tbPwd").SendKeys("password");
session.FindElementByAccessibilityId("btnLogin").Click();
Thread.Sleep(TimeSpan.FromSeconds(5));
session = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), appOptions);
session.Manage().Timeouts().ImplicitWait = TimeSpan.FromMinutes(1);
}
在每个测试用例之后拆除代码
public void TearDown()
{
AppiumOptions appOptions = new AppiumOptions();
appOptions.AddAdditionalCapability("app", "Root");
session = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), appOptions);
// Use the session to control the desktop
session.Keyboard.PressKey(Keys.Command + "r");
session.Keyboard.SendKeys(Keys.Null);
session.Keyboard.SendKeys(@"C:\path of taskkill file.bat"+ Keys.Enter);
//End current session instance
session.Dispose();
}
【问题讨论】:
-
拆解代码对我来说看起来很奇怪......似乎你应该退出会话......(session.quit()?)相反,你正在创建一个新的并运行一个批处理文件?话虽如此,我以前从未使用过 WindowsDriver,所以也许这是必要的?似乎您仍在创建孤立的驱动程序。如果它类似于 webdrivers,quit() 方法应该关闭并处理驱动程序。
-
我最初尝试只使用 session.quit() 来关闭应用程序和会话,但这并没有关闭应用程序,所以我决定使用批处理文件。我正在使用应用程序功能为 Root 而不是路径初始化一个新会话,因为那时我想控制桌面。我也使用了相同的代码,但使用了 session.Quit() 而不是 session.Dispose();。据我了解,出于我的目的,他们正在做同样的事情 - 从内存中清除会话对象。
-
有趣的是,您可以做到这一点... Web 浏览器驱动程序几乎仅限于 DOM。在退出驱动程序之前,您正在那里重写您的会话引用,这意味着您将运行两个 WindowsDrivers(我认为......)。我也会避免使用“session.Dispose()”......这可能无法正确关闭。使用 .quit() ,它可能会在完成后调用 dispose ......然后在必要时调用 dispose() 。如果 WindowsDriver 类似于 WebDriver,quit() 将关闭它所控制的程序,清理,关闭驱动程序,然后处理...(之后引用将为空)
-
应用程序可能需要一些时间才能关闭...请确保在启动新驱动程序之前稍等片刻。 (应用程序可能会在关闭时执行它自己的清理程序,例如保存配置文件,或者与 Windows 驱动程序会话本身有关的事情......驱动程序可能不知道应用程序何时关闭......它只是发送一个命令“关闭”,然后它自己关闭......)你应该只在驱动程序崩溃的情况下需要taskkill。 (关闭它控制的应用程序)
-
我正走在与您相同的思考过程中。我确实使用了.quit(),我将切换回它,但是当我使用它时,我得到了相同的结果。我将 .quit() 与 taskkill 结合使用,因为 .quit() 不会关闭应用程序。我只是在关闭会话后添加了延迟。但是,我现在第一次打开应用程序时就看到了这个问题。 WinAppDriver 在开始测试之前已关闭并重新打开。
标签: selenium selenium-webdriver appium-desktop