标签:
UIAutomation和WPF
UIAutomation是微软从Windows Vista开始推出的一套全新UI自动化测试技术, 简称UIA。在最新的Windows SDK中,UIA和MSAA等其它支持UI自动化技术的组件放在一起发布,叫做Windows Automation API。
和前面的介绍相比,我倾向于认为UIA是一项自动化测试“技术”,而MSAA和Win32 API只是实现自动化测试的两种“方法”。这里区分“技术”和 “方法”的原因是, 一项“技术”往往有独立的模型,体贴的开发接口,用来专门解决某一类的问题,同时允许不同的实现细节。UIA可以被看作“技术”,是因为:
UIA定义了全新的、针对UI自动化的接口和模式。 分别是支持对UI元素进行遍历和条件化查询的TreeWalker/FindAll。定义了读写UI元素属性的UIA Property, 包括Name、 ID、Type、ClassName、Location、 Visibility等等。定义了UI元素行为的UIA Pattern, 比如Select、Expand、Resize、 Check、Value等等。 还引入了UIA Event接口,可以让测试程序在某些事件发生后得到通知,比如新窗口打开事件等。
以往的Win32和MSAA 设计出发点并不是为解决UI自动化。Win32旨在提供的通用开发接口, MSAA旨在提供程序的多种访问方式。相反,UIA的设计目的,以及新引入的模式和接口都完全是针对UI自动化测试的。
在后面的文章中我们会详细分析UIA的内部实现。可以看到,UIA这一套接口和模式,可以在不同平台,不同开发工具中实现和使用。其内部实现方式也因地制宜, 前后的兼容性都照顾得很好。 同时,UIA提供了托管的和非托管两种API,这些都是Win32和MSAA无法比拟的。
UIAutomtion中主要用AutomationElement 类来 表示 UI 自动化目录树中的一个 UI 自动化元素,并包含由 UI 自动化客户端应用程序用作标识符的值。
在reference中添加UIAutomationClient,UIAutomationTypes,UIAutomationProvider 和UIAutomationClientsideProviders。
(Donet 3.0以上的项目中才有)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Automation; using System.Windows; namespace ConsoleApplication2 { class Cal { AutomationElement calcWindow = null; string resultTextAutoId = "150"; string btn5AutoId = "135"; string btn3 = "133"; string btn2 = "132"; string btnPlus = "93"; string btnSub = "94"; string btnEqual = "121"; static void Main(string[] args) { Cal autoClient = new Cal(); //创建新窗口打开事件的回调,只有等计算器窗口打开后,测试开始执行 AutomationEventHandler eventHandler = new AutomationEventHandler(autoClient.OnWindowOpenOrClose); //把事件挂接在桌面根元素,开始监听 Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent, AutomationElement.RootElement, TreeScope.Children, eventHandler); //启动计算器程序,当计算器窗口打开后,新窗口事件得到触发 System.Diagnostics.Process.Start("calc.exe"); Console.ReadLine(); } void OnWindowOpenOrClose(object src, AutomationEventArgs e) { if (e.EventId != WindowPattern.WindowOpenedEvent) { return; } AutomationElement sourceElement; try { sourceElement = src as AutomationElement; //监察印发新窗口打开事件的窗口是否是计算器 //在正式代码中,为了支持本地化测试,字符串应该从资源文件中读取 if (sourceElement.Current.Name == "计算器") { calcWindow = sourceElement; } } catch (ElementNotAvailableException) { return; } //开始执行测试 ExecuteTest(); } private void ExecuteTest() { //执行3+5-2 //调用函数执行按钮点击 ExecuteButtonInvoke(btn3); ExecuteButtonInvoke(btnPlus); ExecuteButtonInvoke(btn5AutoId); ExecuteButtonInvoke(btnSub); ExecuteButtonInvoke(btn2); ExecuteButtonInvoke(btnEqual); //调用getcurrentresult函数,获取计算器输出窗口的值 if (GetCurrentResult() == "6") { Console.WriteLine("execute pass!"); return; } Console.WriteLine("execute faile"); } //调用函数执行按钮点击 private void ExecuteButtonInvoke(string automationId) { //创建捕获按钮条件。该条件中有两个判断 //分别判断automationid是否为指定字符串 //以及控件类型是否为按钮 System.Windows.Automation.Condition conditions = new AndCondition(new PropertyCondition(AutomationElement.AutomationIdProperty,automationId), new PropertyCondition(AutomationElement.ControlTypeProperty,ControlType.Button)); AutomationElement btn = calcWindow.FindFirst(TreeScope.Descendants,conditions); //获取按钮的invokepattern接口 InvokePattern invokeptn = (InvokePattern)btn.GetCurrentPattern(InvokePattern.Pattern); //调用invoke接口,完成按钮点击 invokeptn.Invoke(); } private string GetCurrentResult() { System.Windows.Automation.Condition conditions = new AndCondition(new PropertyCondition(AutomationElement.AutomationIdProperty,resultTextAutoId), new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Text)); AutomationElement btn = calcWindow.FindFirst(TreeScope.Descendants, conditions); //得去text控件的名字,改名字就是输出字符串 return btn.Current.Name; } } }
标签:
原文地址:http://www.cnblogs.com/zhanying/p/4722446.html