基于UI Automation的自动化测试工具设计指南

说明:如下内容是根据2010年我在公司的一次关于UI Automation的Workshop上的PPT整理而来,在公司我和几位同事基于UI Automation开发了一款很是强大的UI自动化测试工具,此工具已经在公司获得普遍运用(有十几个产品采用),用于替代昂贵的、且脚本很难维护的商用软件。此文只探讨UIA相关的一些通用技术和一点点UI自动化测试工具的设计经验,由于保密的须要,涉及到公司的这款测试工具部分此文不作介绍。正则表达式

在没有MSUIA(Microsoft UI Automation,如下简称UIA)以前,你们只能经过MSAA(Microsoft Active Accessibility)、Win32 API等Native的方式来操控Windows控件,要想本身写一个UI自动化测试工具是很难很难的,所以这一领域一直被大厂商所垄断,价格也贵得惊人,不是大的软件公司也是用不起这些工具的(除非盗版),好比QTP、Robot、SilkTest等商用工具。UIA定义了一套全新的、针对UI自动化的接口和模式,以往的Win32和MSAA设计出发点并非为解决UI自动化(Win32旨在提供的通用开发接口,MSAA技术的初衷则是为了方便残疾人使用Windows 程序),而UIA的设计目的(微软也须要一套技术、工具来自动化测试本身的产品)、以及新引入的模式和接口都彻底是针对UI自动化测试的。UIA的出现,让草根UI自动化测试工具成为一种可能,看完本文你如有这样的需求就赶忙本身造一个吧:)架构

在继续介绍UIA以前,你们须要先熟悉UIA的几个名词术语。app

UIA名词解释

Elements

在UIA里,每个UI控件便是一个Automation Element,全部的Elements是存储在一个树状结构中的,Windows的桌面是这颗树的根结点(RootElement)。ide

Tree

UIA tree就是上面所指的树,每一个Application均可以看做是一棵子树。工具

Properties

Element都有一些属性(Properties),好比Automation ID、Name、ControlType等,要找到一个控件主要是经过这些的属性来查找的。测试

Control patterns

在找到一个控件后,对一个控件进行操控的时候就须要用到这个控件支持的控制模式(Control patterns)了,好比:一个TextBox的ValuePattern能够用来获取TextBox里面的文字。ui

Event

当UI控件有什么变更的时候,可能会触发一些事件(好比:弹出HelpText),若是有Client订阅了这个事件则会收到事件的通知。this

UIA的架构

上图左边那部分叫Client,本文指的是UI自动化测试工具,右边叫Application,指的是被测运用程序。Client和Application在启动的时候都会载入UI Automation Core(UIAutomationCore.dll),UI自动化测试工具就是经过UI Automation Core来操控运用程序的。从这个架构图上也能够看到UIA封装了一些MSAA和Win32的接口、屏蔽了Win32和.NET运用程序的差别,UI Automation Core对外提供了统一的接口,这也就大大简化了Client这边的实现。spa

基于UIA这套体系实现UI自动化须要解决的两个核心的问题,一是控件查找(Find Controls);二是控件操做(Control manipulation),下面对此分别进行介绍。设计

控件查找(Find Controls)

UIA除了提供了最基本的遍历整个UIA tree的API(TreeWalker)外,另外也提供了一些Build-in的控件查找API。

TreeWalker

  • GetFirstChild
  • GetNextSibling
  • GetParent

TreeWalker是标准的对UIA tree的遍历API,它是一切控件查找API的基础。

Build-in Finding(基于scope和filting condition的查找API)

  • FindFirst(TreeScope, Condition)
  • FindAll(TreeScope, Condition)

UIA自带的这些Build-in的查找API是基于TreeScope和Filting Condition的,查找控件须要定义一个查找范围和过滤条件。

  • 查找范围(TreeScope)是子结点、子孙结点、父结点等这样的树中的范围定义。
  • 过滤条件(Filting Condition)能够是逻辑条件(AndCondition、 OrCondition、NotCondition等)也能够是属性条件(PropertyCondition)

下面是一个最简单的示例,在RootElement桌面下查找子结点里Name属性是“Simple App”的一个控件,由于是在桌面的子结点(一级),它会是一个Application:

Condition winNameCond = new PropertyCondition(AutomationElement.NameProperty, "Simple App");
 
AutomationElement app = AutomationElement.RootElement.FindFirst(TreeScope.Children, winNameCond)

控件操做(Control manipulation)

经过上面的Find Controls找到一个控件后,接下来就是如何操做它实现UI自动化的问题了,好比:点击一个Button,选择一个TreeViewItem等等。下面是一个已作好封装的UITextBox这个控件类里获取TextBox的文字的参考实现:

public virtual string GetText()
{
    object o = new object();
    if (this.Element.TryGetCurrentPattern(ValuePattern.Pattern, out o))
    {
        ValuePattern pattern = o as ValuePattern;
        return pattern.Current.Value;
    }
    else
    {
        return "";
    }
}

如上面的代码所示,控件操做有一个固定的模式,首先尝试获取控件的Control Pattern,若是控件存在这样的Control Pattern就经过这个Pattern来操控控件,若是没有则须要自定义这个操做或抛出异常等。

UI自动化测试工具设计

直接基于UIA来实现UI自动化不是不能够,但没有人会这么蛮干。为了获取一个Textbox里的文字这样简单的事情,获得处拷贝上面那段的代码,这是不可取的。因此针对上面说的两个核心的问题,咱们须要在UIA上进行一些简化、封装(固然光有这两点是不够的,好比还须要提供一些Native的支持、UI同步、Log等功能,本文对此不作讨论):

简化、强化控件查找

  1. 简化是指简化控件查找API,为了找一个控件就须要写一大堆的Code来定义这样那样的过滤条件(见控件查找部分的示例代码),若是能用一个简单的字符串就统一全部这些那就方便多了,很负责的说咱们就是这么干的,Automation ID、Name、ControlType、Point、Index、或逻辑、与逻辑、通配符、正则表达式、关键路径查找等杂七杂八的各类数据类型通通放到一个字符串里搞定,这也是咱们开发的这个工具很是强大的一个地方。
  2. 强化是指强化控件查找功能,UIA Build-in的查找功能的过滤条件是比较简单的,功能也是很是有限的,好比没有对根据通配符、正则表达式来查找的支持,可是咱们能够经过最基本的TreeWalker的API来扩展实现这样的查找功能。

封装控件的操控

封装经常使用控件的基本操做,如:Button的Click、TreeView的Expand和Collapse、Datagrid的操做等等,使控件的操做变成一个简单的API调用,能够考虑把UIA ControlType里定义的30几种控件中最经常使用的控件基本操做都实现了,这样写测试脚本的时候就很安逸了。一些产品中可能会使用一些非标的控件,对于这些自定义的控件,用标准控件的操控API可能无论用,一般经过下面两种方式来解决这个问题,一是继承标准控件,重写操控API的实现,若是可以实现的话;二是让开发人员改代码,尽可能不要使用非标控件:)

UI自动化测试framework设计

当有了应手的测试工具后,测试脚本的维护依然是个老大难的问题,这个须要有一个好的自动化测试framework来隔离UI的变化,尽可能减小维护成本,一个好的framework大致须要有下面几级的分层:

  1. Core - framework的核心和通用模块,好比:TestCaseBase、Config、WatchDog、Env、OS、DB操做的封装等等。
  2. Dialogs - UI Application、Dialog、Control属性的定义,对于一个大的UI dialog,为了方便组织是能够考虑切片成一些小的虚拟的Dialogs的。在Dialogs尽可能不要涉及操做逻辑,只放属性的定义就能够了。
  3. Key words 或者叫 Wrapper - Key words是按case(测试用例)层面的需求抽象出来的,大致对应到case里的一个操做步骤,这一个操做步骤实际上能够包含在一个或多个UI dialogs上的操做组合,好比:用户登陆能够是一个Key word,但它实际上包含了输入用户名、输入密码、点击登陆按钮等操做步骤。有了Key words对UI Dialog的封装,基本上能够作到在UI变化的时候,只修改Dialogs的定义,Key words的实现代码不多改动,cases的代码则无需修改(只要case的逻辑没有发生变化)。
  4. Test cases - 到了cases层面问题就变得简单了,就是一些Key words的简单组合,再加上一些测试结果的验证就OK了。

总之,经过UIA实现一套本身的强大的UI自动化测试工具不是不可能,但愿本文对一些从事UI自动化测试的同窗有所帮助。

 

原文地址:http://feilong.me/2011/01/ms-ui-automation-tool-design-guide

相关文章
相关标签/搜索