微软提供的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. word 2007,以不同颜色突出显示文本的快捷键,highlight命令

    命令:highlight 默认快捷键:Ctrl+Alt+H   查询或自定义快捷键的方法: 打开一个文档→单击左上角的office图标→word选项 左边的列表中选择自定义→在右边的窗口中,底部有个“ ...

  2. BZOJ3489:A simple rmq problem

    浅谈\(K-D\) \(Tree\):https://www.cnblogs.com/AKMer/p/10387266.html 题目传送门:https://lydsy.com/JudgeOnline ...

  3. ajax中error函数参数详解

    xhr.status和error函数中的status是不一样的,error函数中的status主要包括:"success"."notmodified".&quo ...

  4. LeetCode第五题:Longest Palindromic Substring

    Given a string s, find the longest palindromic substring in s. You may assume that the maximum lengt ...

  5. Angular5学习笔记 - 路由管理(五)

    一.添加路由管理引用 打开src/app/app.module.ts文件 import {RouterModule} from '@angular/router'; import {Routes} f ...

  6. composer的安装和使用

    由于工作中需要用到leancloud的LeanCloud PHP SDK,支持composer安装,所以就下载composer工具了, 安装之前可以用composer命令检测是否已经安装了,命令是:c ...

  7. JSF在ui:include中传递参数到对应控制层

    在JSF中使用ui:include方法可以引入一个页面到当前页面中,如果要向被包含的页面中传入参数,可以使用ui:param标签,这个标签类似于f:param,只不过一个用于页面,一个用于实际标签.示 ...

  8. List<T> JIT 分配策略

    参考 http://www.cnblogs.com/brookshi/p/5353021.html defaultCapacity意思是new List<T>时默认大小是4. _items ...

  9. Shell编程进阶 2.2 shell数组

    给一个字符指定一个数组 怎么显示数组 a= echo $a a=( ) echo $a echo ${a[@]} echo ${a[*]} 指定显示数组中第几个数字 echo ${a[]} echo ...

  10. iOS 给Main.storyboard 添加button 事件《转》

    XCODE中使用Main.Storyboard拉入控件并实现事件(Swift语言)   如何在XCODE中的Main.Storyboard内拉入控件并实现一个简单的效果呢?本人由于刚接触Swift语言 ...