DevExpress技术交流群3:700924826 欢迎一起进群讨论
DevExpress WPF 拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。
在v20.2版本中,技术团队增强了对WPF产品线UI测试自动化的支持,UI自动化现在包括更全面的自动化测试功能:
- DevExpress WPF控件形成与主题无关的AutomationPeer层次结构。
- 您可以在自动化树中搜索AutomationPeer属性,生成和分配的XAML/代码AutomationPeer属性均可用于搜索。
- AutomationPeers包括各种自动化模式,例如Invoke, ExpandCollapse, Selection, Scroll等。
您可以使用UIAutomationClient库API创建自动测试,也可以使用基于UI自动化技术的任何UI测试库。
DevExpress WPF控件包含UI测试模式选项,使用时会对应用程序进行以下更改:
- 动画被禁用。
- 上下文菜单仅在单击鼠标时激活,并且当鼠标指针悬停菜单项时不会打开。
- 修改了UI自动化树,以产生更稳定和可靠的测试。
注意:我们使用Appium WinAppDriver API测试了控件。
准备环境
- 启用Windows Developer Mode。
- 安装WinAppDriver。
- 下载WinAppDriver UI Recorder。
创建测试
请按照以下步骤创建一个新的测试项目:
1. 打开Windows命令提示符,创建项目文件夹或导航到现有文件夹,然后使用以下命令:
- dotnet new nunit --framework netcoreapp3.1 - 创建一个空的nunit测试项目。
- dotnet add package Appium.WebDriver - 在您的项目中引用Appium.WebDriver包。
2. 在Visual Studio中打开nunit测试项目。
3. 创建一个DesktopSession类,该类使您可以使用WinAppDriver UI记录器将生成的代码。
您可以在下面看到是如何实施的:
public class DesktopSession { const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723/"; WindowsDriver < WindowsElement > desktopSession; public DesktopSession(WindowsDriver < WindowsElement > source) { desktopSession = source; } public WindowsDriver < WindowsElement > DesktopSessionElement { get { return desktopSession; } } public WindowsElement FindElementByAbsoluteXPath(string xPath, int nTryCount = 10) { WindowsElement uiTarget = null; var index = xPath.IndexOf(value: '/', startIndex: 1); xPath = xPath.Substring(startIndex: index); while (nTryCount-->0) { try { uiTarget = desktopSession.FindElementByXPath(xpath: $ "/{xPath}"); } catch { Console.WriteLine($@"Find failed: ""{xPath}"""); } if (uiTarget != null) break; Thread.Sleep(millisecondsTimeout: 100); } return uiTarget; } public IOptions Manage() { return this.desktopSession.Manage(); } public void CloseApp() { this.desktopSession.CloseApp(); } }
4. 将以下test fixture复制并粘贴到UnitTest1.cs文件中:
public class Tests { Process pWad; const string PathToTheDemo = @"C:\Users\Public\Documents\DevExpress Demos 20.2\Components\WPF\DevExpress.OutlookInspiredApp.Wpf\bin\DevExpress.OutlookInspiredApp.Wpf.exe"; protected DesktopSession desktopSession { get; private set; } [OneTimeSetUp] public void FixtureSetup() { StartWAD(); var options = new AppiumOptions(); options.AddAdditionalCapability(capabilityName: "app", capabilityValue: PathToTheDemo); options.AddAdditionalCapability(capabilityName: "deviceName", capabilityValue: "WindowsPC"); options.AddAdditionalCapability(capabilityName: "platformName", capabilityValue: "Windows"); var driver = new WindowsDriver < WindowsElement > (new Uri("http://127.0.0.1:4723"), options); desktopSession = new DesktopSession(driver); WaitSplashScreen(driver); } static void WaitSplashScreen(WindowsDriver < WindowsElement > driver) { var cwh = driver.CurrentWindowHandle; while (driver.WindowHandles.Contains(cwh)) Thread.Sleep(1000); driver.SwitchTo().Window(driver.WindowHandles[0]); } private void StartWAD() { var psi = new ProcessStartInfo(@"C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe"); psi.EnvironmentVariables.Add("DX.UITESTINGENABLED", "1"); pWad = Process.Start(psi); } [OneTimeTearDown] public void FixtureTearDown() { desktopSession.CloseApp(); pWad.Kill(); } [SetUp] public void Setup() {} [Test] public void Test1() { Assert.Pass(); } }
FixtureSetup方法执行以下操作:
- 调用StartWAD方法,该方法启动WinAppDriver.exe并启用UI测试模式。
- 创建一个新的Appium测试会话。
- 调用WaitSplashScreen方法并在应用程序加载操作期间挂起测试。
UI测试模式
将DevExpress WPF控件切换到UI测试模式,为此请将被测应用程序(在应用程序启动时)将DX.UITESTINGENABLED环境变量设置为1或将ClearAutomationEventsHelper.UITestingEnabled 属性设置为true。此模式产生以下变化:
- 动画被禁用。
- 上下文菜单仅在单击鼠标时激活,并且当鼠标指针位于菜单上方时不会打开。
- 修改了UI自动化树,以产生更稳定和可靠的UI测试。
记录测试
请按照以下步骤记录测试:
1. 以管理员身份运行WinAppDriver UI记录器。
2. 在Test1方法中设置一个断点。
3. 调试Test1测试,这将运行OutlookInspired演示应用程序并启用UI测试模式。
4. 单击WinAppDriver UI记录器窗口中的Record按钮。
将鼠标悬停在New Employee按钮上,然后等待,直到记录器在按钮周围显示蓝色边框为止。 这意味着记录器已准备好捕获输入,点击按钮。
将鼠标悬停在First Name文本字段上,然后等待,直到记录仪准备好捕获输入,输入一个值。
对Last Name、Title、Mobile Phone和Email文本字段重复上一步。
记录Save & Close按钮的点击。
5. 在Recorder窗口中,单击Pause and copy按钮将生成的代码复制到剪贴板。
缺点
上面概述的方法有一些缺点:
- 这些测试使用FindElementByXPath方法查找元素,这种方法很慢,因为它解析了整个可视树。 在我们的测试机上,测试耗时1分32秒。
- 这些测试很难维护,因为它们使用绝对XPath来定位元素,对应用布局的更改可能会破坏测试。
- 这些测试很难阅读。
重写测试
我们可以重写测试以解决上述问题(并加快测试速度)。 您可以分析记录的xpath或使用检查工具来获取元素属性,例如Names、ClassNames和AccessibilityIds。
使用WinAppDriver的FindElementByName、FindElementByClassName和FindElementByAccessibilityId方法查找应用程序元素,这些方法比FindElementByAbsoluteXPath方法要快。 修改应用程序的布局时,基于这些方法的测试不会失败。
[Test][Order(0)] public void CreateEmployee() { var desktopElement = desktopSession.DesktopSessionElement; var bNewEmployee = desktopElement.FindElementByName("New Employee"); bNewEmployee.Click(); WindowsElement newEmployeeWindow = null; while (newEmployeeWindow == null) newEmployeeWindow = desktopElement.FindElementByName("Employee (New)"); newEmployeeWindow.FindElementByName("First Name").FindElementByClassName("TextEdit").SendKeys("John"); newEmployeeWindow.FindElementByName("Last Name").FindElementByClassName("TextEdit").SendKeys("Doe"); newEmployeeWindow.FindElementByName("Title").FindElementByClassName("TextEdit").SendKeys("CTO"); newEmployeeWindow.FindElementByName("Mobile Phone").FindElementByClassName("ButtonEdit").SendKeys("1111111111"); newEmployeeWindow.FindElementByName("Email").FindElementByClassName("ButtonEdit").SendKeys("john.doe@dx-email.com"); newEmployeeWindow.FindElementByName("Save & Close").Click(); }
重写后的测试仅需25秒。