https://segmentfault.com/a/1190000010339021

从事Windows 桌面应用自动化测试也有一些年了,现在谈这个话题并不流行。因为除了企业级应用,很少有公司会只选择Windows桌面作为目标用户平台,一般都会考虑跨平台的浏览器解决方案,桌面应用的地位渐渐下降,这是事实。

当年初入测试行业时就被外包公司看上了,在微软的圈子里一待就是4年,时间真快。不得不说,一个大学刚毕业的毛头小子看到微软里各种技术和工具真像极了刘姥姥进大观园,那时候还没有iPhone,也没有Android,微软一统天下。

本文主要介绍一下我对Windows UI自动化的一些看法以及WPATH的实现和应用,如果你还在从事Windows桌面应用的自动化测试,应该能有一些帮助。

为何发明WPATH

Windows UI 自动化,顾名思义就是在Windows平台实现软件的界面自动化,比如自动打开Excel填入一些数据,输入公式,获取结果。正经的用途就是软件自动化测试,避免重复的手工操作;不正经的用途就是写外挂,各种投机取巧的工具等等。

最简单粗暴的实现方案就是录制回放,优点很明显,简单快速;缺点也一样明显,不可靠因素太多。主要的代表就是QTP,来自HP公司,这应该是很多同学都听过的一款测试工具。

进阶的方案就是使用微软提供的自动化工具集:UI Automation。UI Automation是Microsoft .NET 3.0框架下提供的一种用于自动化测试的技术,是在MSAA基础上建立的,MSAA就是Microsoft Active Accessibility。

如果你使用过.NET 提供的UI Automation相关的类库,应该有一个直观的感受,就是非常啰嗦,举一个例子:

AutomationElement ControlTypeComboBox = grdClassBook.FindFirst(
TreeScope.Children,
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ComboBox)); AutomationElement cellElement = ControlTypeComboBox.FindFirst(
TreeScope.Children,
new PropertyCondition(AutomationElement.AutomationIdProperty, "ListBox"));

每当你尝试去获取一个UI元素时,都需要使用FindFirst之类的方法去查询指定的PropertyCondition,而PropertyCondition使用起来也不简单,特别是当你需要拼接多个AND或者OR多个条件时。

var btnCondition = new AndCondition(
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button),
new PropertyCondition(AutomationElement.NameProperty, "ok"));

才两个条件就这么多代码了?你看看搞Web自动化的同学都可以用XPATH,快速定位和查询元素 /div[@id='ok'],多好。既然我们那么羡慕XPATH,那我们就搞一个出来,让做Windows桌面自动化的同学也可以High一把。

WPATH实现原理

具体代码我就不在此赘述了,想读代码的同学可以直接移步至Github:https://github.com/tobyqin/wpath

WPATH的主要原理就是通过反射的方式去获取当前方法或者属性的Attribute,在Attribute中我们可以定义类似于XPATH的语法,我 且称之为WPATH。最后经过表达式解析转换成对应的Find方法和Condition,举一个例子说明:

[WPath("/Edit[@id='txtId' or @Class='TextBox']")]
public AutomationElement EditControl
{
get { return this.AppElement.FindByWPath(); }
}

当调用FindByWPath()时,该属性上的WPath Attribute就会被解析出来,其中的 /会被解析成FindFirst,Edit会被解析成ControlType.Edit,中括号里的条件最后被组合起来,调用的最终结果大致如下:

public AutomationElement EditControl
{
get
{
return this.AppElement.FindFirst(TreeScope.Children,
new AndCondition(
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit),
new OrCondition(
new PropertyCondition(AutomationElement.AutomationId, "txtId"),
new PropertyCondition(AutomationElement.Class, "TextBox"))));
}
}

痛苦的感觉一下减轻许多,有没有?

更详细的WPATH用法

如果你要在项目中使用WPATH,可以通过nuget包安装:

PM> Install-Package WPath

简单说明

  1. WPath 和 XPath 类似,以 '/' 开头。

  2. 可以使用多个 '/' 来定位目标元素。

  3. 节点名字来自于MSDN定义好的 control type

  4. 目前WPath支持的查询属性如下:

  • Name (NameProperty)

  • ID (AutomationIdProperty)

  • Class (ClassNameProperty)

  • Enabled (IsEnabledProperty)

  • FrameworkID (FrameworkIdProperty)

举例子

/Group/Button

  • 获取第一个Group下的第一个Button。

//Button[@Name='Save']

  • 在子孙节点中获取第一个Name为 "Save" 的元素。

/[@Name='TabContainer']/Button[2]

  • 获取Name为 "TabContainer"的控件下的第二个Button,注意,控件类型名称可以为空。

/Button[@ID='AddButton' and @Name='Add']

  • 获取一个automation ID 为 'AddButton'  name 为 'Add' 的Button。

/Button[@ID='AddButton' or @Name='Add']

  • 获取一个automation ID 为 'AddButton'  name 为'Add'的Button。

/Button[first()]

  • 获取当前元素下第一个Button。

/Button[last()]

  • 获取当前元素下最后一个Button。

实际运用

推荐使用Attribute的方式进行调用,可用于类方法或者属性。

[WPath("/Edit[@id='txtId' or @Class='TextBox']")]
public AutomationElement EditControl
{
get { return this.AppElement.FindByWPath(); }
} [WPath("/Button[first()]")]
public AutomationElement GetFirstButton()
{
return this.AppElement.FindByWPath();
}

或者直接调用 FindByWPath(path) 来定位目标元素。

var path = "/Edit[3]";
var e = this.AppElement.FindByWPath(path);
Assert.AreEqual("txtKey", e.Current.AutomationId);
Assert.AreEqual(ControlType.Edit, e.Current.ControlType); path = "/Button[@name='OK']/Text[1]";
e = this.AppElement.FindByWPath(path);
Assert.AreEqual("OK", e.Current.Name);
Assert.AreEqual(ControlType.Text, e.Current.ControlType);

小贴士

  • 元素类型节点是大小写不敏感的,比如:

    • @name = @Name

    • /edit = /Edit

  • 父节点定位 ../ 目前不支持,因为有点复杂。

更多的说明建议还是去看Github中的说明文档,或者直接看单元测试

后记

Windows UI 自动化的坑还是挺深的,填坑的人也不少,我推荐有需要的同学去学习和了解一下 White。White是一个非常好UI Automation 封装框架,相信我,能省下你不少时间。

Windows UI自动化测试的XPATH实现 - WPATH的更多相关文章

  1. 从UI Automation看Windows平台自动化测试原理

    前言 楼主在2013年初研究Android自动化测试的时候,就分享了几篇文章 Android ViewTree and DecorView Android自动化追本溯源系列(1): 获取页面元素 An ...

  2. 对Windows桌面应用程序进行UI自动化测试

    题记:本文简述如何利用appium对Windows桌面应用程序进行UI自动化测试. 所谓UI自动化测试,就是模拟一个用户,对应用程序的UI进行操作,以完成特定场景的功能性集成测试. 要对Windows ...

  3. 基于Appium的UI自动化测试

    为什么需要UI自动化测试 移动端APP是一个复杂的系统,不同功能之间耦合性很强,很难仅通过单元测试保障整体功能.UI测试是移动应用开发中重要的一环,但是执行速度较慢,有很多重复工作量,为了减少这些工作 ...

  4. 使用WatiN进行UI自动化测试

    Watin是一个UI自动化测试工具,支持ie/firefox,官方网站:http://watin.org/. 主要有以下特点: 支持主要的html元素,见:http://watin.org/docum ...

  5. 【转】Web UI自动化测试原理

    目前市面上有很多Web UI自动化测试框架,比如WatiN, Selinimu,WebDriver,还有VS2010中的Coded UI等等.  这些框架都可以操作Web中的控件,模拟用户输入,点击等 ...

  6. UI自动化测试(三)对页面中定位到的元素对象做相应操作

    前两天分别讲述了UI自动化测试基础以及对页面元素该如何进行定位,这一篇自然就是对定位到的页面元素对象进行相应操作啦. 阅读目录 1.常用操作元素对象的方法 2.鼠标事件操作 3.键盘事件操作 4.We ...

  7. <自动化测试方案_7>第七章、PC端UI自动化测试

    第七章.PC端UI自动化测试 UI自动化测试又分为:Web自动化测试,App自动化测试.微信小程序.微信公众号UI层的自动化测试工具非常多,比较主流的是UFT(QTP),Robot Framework ...

  8. [原创]浅谈Web UI自动化测试

    [原创]浅谈Web UI自动化测试 Web UI自动化测试相信大家都不陌生,今天来谈谈这个,我最早接触自动化测试时大约是在2004年,2006年当时在腾讯财付通算是开始正式接触自动化测试,之所以是正式 ...

  9. 浅谈UI自动化测试

    最近一直在学习python,正好部门技术结构调整,就开始了点工向UI自动化测试的转变,我要说瞌睡来了就掉枕头么? 不过还好,可以将python的学习成果在自动化测试中实践... 1.about自动化测 ...

随机推荐

  1. 遍历 HashSet 的方法

    遍历 HashSet 的方法 import java.util.HashSet; import java.util.Iterator; import java.util.Set; public cla ...

  2. kubenetes之配置pod的QoS

    系列目录 上节提到过,QoS影响pod的调度和驱离,本节讲解如何通过配置pod来使它自动被赋予一个QoS 实际上是pod的配置达到一定标准,则kubernetes会自动为其它添加一个QoS类 QoS类 ...

  3. @interface __ annotation 子类可以继承到父类上的注解吗--有结论了

    博客分类: Java/J2se   作者:赵磊 博客:http://elf8848.iteye.com 不了解注解基础知识的请先看<JDK 5 Annotation\注解\注释\自定义注解> ...

  4. HashMap源码原理

    HashMap源码解析(负载因子,树化策略,内部hash实现,resize策略) 内部属性: 负载因子: final float loadFactor(默认为0.75f) 实际容量: int thre ...

  5. Smobiler客户端会话

    //客户端会话存值 Client.Session["userid"] = Class1.userid; //客户端会话取值 userid = Client.Session[&quo ...

  6. 两数相加(C#数据结构和算法练习)

    两数相加 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表 ...

  7. intel AVX指令集

    听说这 AVX 很牛,,支持Win7,大幅提高游戏浮点运算性能warning C4752: 发现 Intel(R) 高级矢量扩展:请考虑使用 /arch:AVX

  8. Configuration property name 'xxx' is not valid

    目录 问题 解决 问题 程序出错:Configuration property name ‘xxx’ is not valid, Canonical names should be kebab-cas ...

  9. 阿里和Google的JAVA开发规约

    <阿里 JAVA开发规约> 阿里巴巴Java开发手册终极版v1.3.0.pdf 出处:github地址:https://github.com/alibaba/p3c <Google ...

  10. [echart] webpack中安装和使用

    安装echart npm install echarts --save 全量引入 可以直接在项目代码中 require('echarts') 得到 ECharts. 官方示例 var echarts ...