微软提供的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. 程序员转项目管理之考证PMP

    转行项目经历是IT人的出路之一,最近身边有好几个同事都在备考PMP,从个人未来职业发展来看,如果你有将来转行项目管理的想法,应该去尝试考一下PMP. PMP(Project Management Pr ...

  2. testng监听ISuiteListener

    实现ISuiteListener public class TestNgBeforeAction implements ISuiteListener{ public void onStart(ISui ...

  3. CentOS 7.2 PowerShell下安装Azure Module

    目前Linux版本的PowerShell还是Alpha版本,所以很多功能不能使用. 比如通过Powershell命令:install-module AzureRM在线安装Azure的Module.但我 ...

  4. Dubbo实现RPC调用使用入门

    使用Dubbo进行远程调用实现服务交互,它支持多种协议,如Hessian.HTTP.RMI.Memcached.Redis.Thrift等等.由于Dubbo将这些协议的实现进行了封装了,无论是服务端( ...

  5. Oracle 高可用作业测试

    1.RAC 是一种: A 分布式数据库B 内存共享多节点数据库C 能够保护数据安全的架构 2.RAC 和CRS 的区别是: A 前者表示一种架构,后者是一套软件B 前者表示一套软件,后者是一种架构 C ...

  6. Ubuntu14.04LTS上安装Pip

    pip是一个安装和管理Python包的工具.在Pip的帮助下,你可以安装独特版本的包. 最重要的是,Pip可以通过一个“requirements”的工具来管理一个由包组成的列表和版本号. Pip很像e ...

  7. IDEA 运行spingboot时出现Process finished with exit code -1073741819 (0xC0000005)

    经过多方查证,问题最终定位在金山词霸2016上,如果开启了金山词霸的取词和划意功能,就会出现此错误,估计是冲突吧. 解决办法:关掉金山词霸,或者把金山词霸的取词和划意功能关掉.经过尝试,发现只要在ID ...

  8. PhoneGap打Android包报错

    1.下载AndroidSDK,安装 2.下载Phonegap,解压,为以后打包用 3.下载Node.js,安装 4.下载并安装Ant工具 5.配置环境变量 ANT_HOME=ANT主目录路径 PATH ...

  9. HTML5实用知识点

    本文讲解HTML5实用知识点 新增的表单type Canvas使用 SVG使用 Audio使用 Video使用 网页缓存 文件缓存 后台worker Server-Sent Events 定位 拖放功 ...

  10. 11-13SQLserver基础--数据库之事务

    事务 定义:在远程操作时,都要经过两步操作,先删除后插入或者先插入后删除,都要调用两次数据库,为了保证数据库的完整性,只要流程运转过程中,只要有一步操作未成功,自动复原,回到流程刚开始的地方.实际上是 ...