关于UI Automation框架
微软提供的UI Automation框架给开发windows平台的自动化测试带来了很大的便利,这里就总结一下相关的代码。
首先,直接使用UI Automation框架,完成一个NotePad的about窗口中的 “OK” button的点击:
AutomationElement root = AutomationElement.RootElement;
AutomationElement about_notepad_windows = root.FindFirst(
TreeScope.Descendants,
new AndCondition(
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window),
new PropertyCondition(AutomationElement.NameProperty, "About Notepad")));
if (about_notepad_windows == null)
{
Console.WriteLine("About Notepad window doesn't exist!!");
return;
} AutomationElement ok_button = about_notepad_windows.FindFirst(
TreeScope.Children,
new AndCondition(
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button),
new PropertyCondition(AutomationElement.NameProperty, "OK")));
Object invokePatternObject;
if (ok_button.TryGetCurrentPattern(InvokePattern.Pattern, out invokePatternObject))
{
(invokePatternObject as InvokePattern).Invoke();
}
好吧,上面是面向过程的代码,不利于复用,那么让我们来将其抽象成类,
首先定义一个基类UIAControl,它包含有搜索的根节点searchRoot,搜索范围searchScope和条件searchConditions,使用这三个对象来搜索一个AutomationElement对象并将其赋给innerElement,由于默认使用的是AndCondition来关联所有传入的condition对象,所以将CombineCondition方法设为虚方法,以便如果有子类想要使用其他关联条件处理condition的时候可以覆盖:
public abstract class UIAControl
{
private UIAControl searchRoot;
private TreeScope searchScope;
private List<Condition> searchConditions; protected void AddSearchCondition(Condition condition)
{
this.searchConditions.Add(condition);
} public UIAControl()
{
searchConditions = new List<Condition>();
searchScope = TreeScope.Descendants;
} public UIAControl(UIAControl searchRoot)
: this()
{
this.searchRoot = searchRoot;
} public UIAControl(IntPtr hwnd)
: this()
{
searchConditions.Add(PropertyConditionFactory.GetHandleCondition(hwnd));
} public AutomationElement.AutomationElementInformation? ControlInformation
{
get
{
if (Exists())
{
return InnerElement.Current;
}
return null;
}
} private AutomationElement innerElement;
public AutomationElement InnerElement
{
get
{
if (innerElement == null)
{
innerElement = SearchElement();
}
return innerElement;
}
} protected virtual AutomationElement SearchElement()
{
AutomationElement ele = null;
if (searchRoot == null)
{
ele = AutomationElement.RootElement;
}
else
{
ele = searchRoot.InnerElement;
} if (ele == null || == searchConditions.Count)
{
return ele;
}
else
{
Condition conditions = CombineAllConditions();
try
{
return ele.FindFirst(searchScope, conditions);
}
catch(Exception ex)
{
Console.WriteLine("Getting exception when searching element: " + ex.Message);
return null;
}
}
} //Can override this method to return other type conditions, default will return AndCondition
protected virtual Condition CombineAllConditions()
{
if (searchConditions.Count > )
{
return new AndCondition(searchConditions.ToArray());
}
else if (searchConditions.Count == )
{
return searchConditions.First();
}
else
{
return null;
} } public virtual bool Exists()
{
//Before checking existence, set innerElement to null to trigger fresh search.
return null != SearchElement();
} public bool WaitTillExist(int timeout, int interval = )
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (stopwatch.ElapsedMilliseconds < timeout)
{
if (this.Exists())
{
return true;
} Thread.Sleep(interval);
} return false;
} protected bool CallPattern<T>(T pattern, Action<T> action) where T : BasePattern
{
if (pattern != null)
{
try
{
action(pattern);
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
return false;
} protected T GetPattern<T>() where T : BasePattern
{
var ele = InnerElement;
if (ele != null)
{
try
{
var patternIdentifier = (AutomationPattern)(typeof(T).GetField("Pattern").GetValue(null));
return ele.GetCurrentPattern(patternIdentifier) as T;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
return null;
} public bool Invoke()
{
return CallPattern(GetPattern<InvokePattern>(), (pattern) => pattern.Invoke());
}
}
之后,就可以定义其他控件类型了,下面定义了一个button的对象,只有一个click方法:
public class UIAButton : UIAControl
{
public UIAButton(UIAControl root, string name)
: base(root)
{
AddSearchCondition(PropertyConditionFactory.GetNameCondition(name));
AddSearchCondition(PropertyConditionFactory.GetControlTypeCondition(ControlType.Button));
} public void Click()
{
this.Invoke();
}
}
再定义一个window对象:
public class UIAWindow : UIAControl
{
public UIAWindow(string name)
{
AddSearchCondition(PropertyConditionFactory.GetNameCondition(name));
AddSearchCondition(PropertyConditionFactory.GetControlTypeCondition(ControlType.Window));
} public bool Close()
{
return CallPattern(GetPattern<WindowPattern>(), (pattern) => pattern.Close());
} public bool Maximize()
{
return CallPattern(GetPattern<WindowPattern>(), (pattern) => pattern.SetWindowVisualState(WindowVisualState.Maximized));
} public bool Minimize()
{
return CallPattern(GetPattern<WindowPattern>(), (pattern) => pattern.SetWindowVisualState(WindowVisualState.Minimized));
} public bool Resize(int width, int height)
{
return CallPattern(GetPattern<TransformPattern>(), (pattern) => pattern.Resize(width, height));
}
}
最后,使用上面两个控件类型来完成Ok按钮的点击:
UIAWindow windows = new UIAWindow("About Notepad");
UIAButton ok_button = new UIAButton(windows, "OK");
if (windows.WaitTillExist())
{
ok_button.Click();
}
当然,如果是稍微上点规模的项目,就需要利用这些控件抽象出一个对应产品功能的produc类了。
如果不想从头写起的话,可以看看开源工具White, 一个优秀的基于UI Automation的测试框架。
关于UI Automation框架的更多相关文章
- UI Automation的两个成熟的框架(QTP 和Selenium)
自己在google code中开源了自己一直以来做的两个自动化的框架,一个是针对QTP的一个是针对Selenium的,显而易见,一个是商业的UI automation工具,一个是开源的自动化工具. 只 ...
- MS UI Automation Introduction
MS UI Automation Introduction 2014-09-17 MS UI Automation是什么 UIA架构 UI自动化模型 UI自动化树概述 UI自动化控件模式概述 UI 自 ...
- 使用UI Automation实现自动化测试--1
Introduction UI Automation是Microsoft .NET 3.0框架下提供的一种用于自动化测试的技术,是在MSAA基础上建立的,MSAA就是Microsoft Active ...
- Visual Studio UI Automation 学习(三)
昨天了解到UI Automation是微软的.Net Framework框架里的4个DLL文件,可以在Visual studio里写代码时引入引用和引用命名空间.然后去写自动化代码. 今天本来是跟着一 ...
- Visual Studio UI Automation 学习(二)
今天恰好有时间,继续学习了一下UI Automation的知识.看了两篇博客,对UI Automation有了进一步的了解. https://blog.csdn.net/qq_37546891/art ...
- Visual Studio UI Automation 学习(一)
这几天需要研究自动化测试工具,因为团队开发使用visual studio,所以需要研究一下Visual studio自带的框架. 刚开始安装的时候,没有选自定义安装,所以安装完成后没有找到UI Aut ...
- 简单Web UI 自动化测试框架 pyse
WebUI automation testing framework based on Selenium and unittest. 基于 selenium 和 unittest 的 Web UI自动 ...
- 使用UI Automation实现自动化测试--1-4
Introduction UI Automation是Microsoft .NET 3.0框架下提供的一种用于自动化测试的技术,是在MSAA基础上建立的,MSAA就是Microsoft Active ...
- 避免重复造轮子的UI自动化测试框架开发
一懒起来就好久没更新文章了,其实懒也还是因为忙,今年上半年的加班赶上了去年一年的加班,加班不息啊,好了吐槽完就写写一直打算继续的自动化开发 目前各种UI测试框架层出不穷,但是万变不离其宗,驱动PC浏览 ...
随机推荐
- 首次db查询时延迟明显高于后面几次。
1.如果排查到时db相关的问题的话,一般都是连接池的配置问题. 在配置好连接池时一定要注意对连接也进行初始化配置,否则可能出现连接池初始化了,但是连接并没有初始化,这样在第一次查询的时候可能会出现较大 ...
- 我的ubuntu新系统自动装软件脚本
装一些常用软件 配一下环境变量 #!/bin/bash #download g++sudo apt-get install g++ -y#download codeblockssudo apt-get ...
- snmpwalk用法
snmpwalk语法:snmpwalk 交换机或路由器IP地址 -c SNMP读密码 -v 1或2(代表SNMP版本) OID(对象标示符) 用法举例:1.snmpwalk -c public -v ...
- Oracle记录(一)Oracle简介与安装
Oracle笔记(一) Oracle简介及安装 一.轨迹 二.Oracle简介 Oracle是现在全世界最大的数据库提供商,编程语言提供商,应用软件提供商,它的地位等价于微软的地位. Oracle在古 ...
- Asp.NET Core+ABP框架+IdentityServer4+MySQL+Ext JS之验证码
验证码这东西,有人喜欢有人不喜欢.对于WebApi是否需要验证码,没去研究过,只是原来的SimpleCMS有,就加上吧. 在WeiApi上使用验证码,关键的地方在于WeiApi是没有状态的,也就是说, ...
- Linux驱动 - SPI驱动 之三 SPI控制器驱动
通过第一篇文章,我们已经知道,整个SPI驱动架构可以分为协议驱动.通用接口层和控制器驱动三大部分.其中,控制器驱动负责最底层的数据收发工作,为了完成数据的收发工作,控制器驱动需要完成以下这些功能:1. ...
- openwrt 按下回车才能显示图标信息
如题所示,openwrt启动后,手动才能按下系统图标和信息. 如何却掉这个手动选项呢? 修改文件/SISP-L26.7.8-OpenWrt/build_dir/target-arm_uClibc-0. ...
- Day2-VIM(一):移动
基础 字符移动 k 上移 k h 左移 h l l 右移 j j 下移 你也可以使用键盘上的方向键来移动,但这么做h j k l的存在就失去了意义 之所以使用h j k l来控制方向,其主要目的是让你 ...
- java线程面试题及答案
1)2017Java面试题及答案:什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务 ...
- 最全 C 语言常用算法详解-排序-队列-堆栈-链表-递归-树 (面试有用)
具体 源代码 案例查看github,持续更新中............ github地址:https://github.com/Master-fd/C-Algorithm 1. 二分法查找 2. 冒泡 ...