微软提供的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框架的更多相关文章

  1. UI Automation的两个成熟的框架(QTP 和Selenium)

    自己在google code中开源了自己一直以来做的两个自动化的框架,一个是针对QTP的一个是针对Selenium的,显而易见,一个是商业的UI automation工具,一个是开源的自动化工具. 只 ...

  2. MS UI Automation Introduction

    MS UI Automation Introduction 2014-09-17 MS UI Automation是什么 UIA架构 UI自动化模型 UI自动化树概述 UI自动化控件模式概述 UI 自 ...

  3. 使用UI Automation实现自动化测试--1

    Introduction UI Automation是Microsoft .NET 3.0框架下提供的一种用于自动化测试的技术,是在MSAA基础上建立的,MSAA就是Microsoft Active ...

  4. Visual Studio UI Automation 学习(三)

    昨天了解到UI Automation是微软的.Net Framework框架里的4个DLL文件,可以在Visual studio里写代码时引入引用和引用命名空间.然后去写自动化代码. 今天本来是跟着一 ...

  5. Visual Studio UI Automation 学习(二)

    今天恰好有时间,继续学习了一下UI Automation的知识.看了两篇博客,对UI Automation有了进一步的了解. https://blog.csdn.net/qq_37546891/art ...

  6. Visual Studio UI Automation 学习(一)

    这几天需要研究自动化测试工具,因为团队开发使用visual studio,所以需要研究一下Visual studio自带的框架. 刚开始安装的时候,没有选自定义安装,所以安装完成后没有找到UI Aut ...

  7. 简单Web UI 自动化测试框架 pyse

    WebUI automation testing framework based on Selenium and unittest. 基于 selenium 和 unittest 的 Web UI自动 ...

  8. 使用UI Automation实现自动化测试--1-4

    Introduction UI Automation是Microsoft .NET 3.0框架下提供的一种用于自动化测试的技术,是在MSAA基础上建立的,MSAA就是Microsoft Active ...

  9. 避免重复造轮子的UI自动化测试框架开发

    一懒起来就好久没更新文章了,其实懒也还是因为忙,今年上半年的加班赶上了去年一年的加班,加班不息啊,好了吐槽完就写写一直打算继续的自动化开发 目前各种UI测试框架层出不穷,但是万变不离其宗,驱动PC浏览 ...

随机推荐

  1. LeetCode Find Mode in Binary Search Tree

    原题链接在这里:https://leetcode.com/problems/find-mode-in-binary-search-tree/#/description 题目: Given a bina ...

  2. webpack里CommonJS的require与ES6 的module.exports加载模块有何不同

    只需明白commonjs的规则即可,import会被转化为commonjs格式的,babel默认会把ES6的模块转化为commonjs规范的. import vue from 'vue'; //等价于 ...

  3. 开启 intel vt-d

    1.开机后按“DEL”或“F2”进入BIOS: 2.在Advanced选项页中找到System Agent Configuration并选择进入: 3.进入System Agent Configura ...

  4. 最小LINUX系统下U盘的挂载及卸载

    U盘挂载命令U盘插入的时候会显示启动信息,启动信息中sda: sda1指U盘的设备名为sda1dev设备目录下有一个sda1设备文件,此设备文件就是我们插入的U盘,我们将这个设备文件挂载到Linux系 ...

  5. L2-020. 功夫传人(dfs+vector 或者 邻接矩阵+dij+优先队列)

    L2-020. 功夫传人 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 一门武功能否传承久远并被发扬光大,是要看缘分的.一般来 ...

  6. Http工作过程

    一次HTTP操作称为一个事务,其工作整个过程如下: 1 ) .地址解析, 如用客户端浏览器请求这个页面:http://localhost.com:8080/index.htm 从中分解出协议名.主机名 ...

  7. 二 Istio设计的核心原则

    Istio架构关键目标 最大化透明度:Istio将自身自动注入到服务间所有的网络路径中.Istio使用sidecar代理来捕获流量,并且在尽可能的地方自动编程网络层,通过代理来路由流量,无需改动应用程 ...

  8. 【ZooKeeper怎么玩】之一:为什么需要ZK

    博客已经搬家,见[ZooKeeper怎么玩]之一:为什么需要ZK 学习新东西首先需要搞清楚为什么学它,这是符合我们的一个认知过程.<!--more-->#ZooKeeper是什么ZooKe ...

  9. php学习之try catch

    PHP 5 添加了类似于其它语言的异常处理模块.在 PHP 代码中所产生的异常可被 throw语句抛出并被 catch 语句捕获.(注:一定要先抛才能获取) 需要进行异常处理的代码都必须放入 try ...

  10. redis学习二 排序

    文章转载自:http://www.cnblogs.com/redcreen/archive/2011/02/15/1955226.html redis支持对list,set和sorted set元素的 ...