0
回答
类jQuery selector的UI自动化测试用控件查询iQuery开源类库介绍
华为云实践训练营,热门技术免费实践!>>>   

整个iQuery的代码是开源的,今后也将有后续文章讲解iQuery的实现方式,对iQuery有兴趣的朋友可以在此下载或者同步代码:

https://github.com/vowei/iQuery

在程序界面(UI)自动化测试中,最烦人的就是抓取控件的过程了,要么是程序员忘记在代码里给控件添加自动化测试用的标签;要么就是界面布局经常 变,如果是基于坐标位置抓取的话,一点小变化都很麻烦。碰到这种问题很讨厌,界面变更导致的测试失败由于跟产品问题无关,因此开发一方经常会拒绝修改代 码,问题全部丢给测试工程师一方。而在手机应用上,这种问题就更突出了,一个市场占有率较广的应用通常都支持好几个平台,而各个平台的编程方式还不一 样……

iQuery的思路借鉴自jQuery(或者说是CSS)的选择器,一方面提供一个比较简单的方式在自动化测试程序里抓取控件,一方面试图通过将控 件归类提供一种跨平台统一的控件抓取表述语法。它是一个多平台通用的控件查询语法,当前已经实现了iOS版,支持在Instrument里使用,本文介绍 iQuery在iOS上Instrument中的用法。

我们尽量将iQuery的语法与jQuery的语法保持一致,然而由于二者的目标不一致(jQuery致力于尽可能多的抓取控件,而iQuery则致力于以最快的速度抓取目标控件),所以iQuery和jQuery的语法有一些细微的差别。

我们以下面的程序为例说明iQuery的语法和在iOS上的用法:

  TestUIDemo_iOS

其对应的控件树形式为,控件树和后面的示例图片都是从HierarchyViewer-4-iOS上获取的:
HierarchyViewer-4-iOS工具的使用说明请参见文章:

http://www.cnblogs.com/vowei/archive/2012/08/13/2614468.html
其源代码也是开源的:
https://github.com/vowei/HierarchyViewer-4-iOS


 TestUIDemo_ControlTree

下面是几个iQuery语法示例,更详细的示例以及文档请参考网页http://www.vowei.com/iquery-1.html):

要在Instrument中使用iQuery,只要在自动化测试用例的脚本中引入iquery.js文件即可,如下所示:

在后面的例子中,下面root和assert是两个全局变量,root表示当前应用的主窗口。

var root = target.frontMostApp().mainWindow();var assert = new Assert();

跟jQuery类似,iQuery的查询操作函数名也是$,函数声明如下:

$(selector, context)

1、跟jQuery类似,iQuery也可以省略查询起始的控件位置(即context参数),那样的话默认从应用的当前窗口开始查询:

test("([attr (>|<|>=|<=) float])比较属性值", function() {
    var query = "> [value >= 59%]";  
    var result = $(query);
    assert.Equals(1, result.length);

    query = "> [:height > 31]";
    result = $(query);
    assert.Equals(6, result.length);
    for ( var i = 0;i < result.length; ++i ) {
    assert.True(result[i].rect().size.height > 31);
}

    query = "UIAWindow > UIASegmentedControl > UIAButton :eq(0) + UIAButton";
    result = $(query);
    assert.Equals(1, result.length);
    assert.Equals("Second", result[0].name());
});

上例中:
$("> [:height > 31]")的意思在默认的当前界面主窗口下,在其子控件列表里查找高度大于31个像素点的控件,其中我们叫它:height 伪属性,所有在方括号内,以英文冒号开头的都被称作伪属性,为了统一表示多个平台,有些平台例如Android实现了控件的height属性,而有些平台 例如iOS上就没有实现这个属性,是通过rect属性获取的。为了在多个平台上统一表达这些差异,我们将这些差异抽象成伪属性的概念。

$("> [value >= 59%]")的意思在默认的当前界面主窗口下,在其子控件列表里查找具有名为“value”的属性,且其值大于59%的控件。如下图所示:

TestUIDemo_ControlTree_Details

$("UIAWindow > UIASegmentedControl > UIAButton :eq(0) + UIAButton")的意思是在指定的上下文控件(即当前窗口对象)中,先匹配类型名为“UIAWindow”的控件也就是窗口对象本身,在其子控件列 表中过滤出类型名为“UIASegmentedControl”的控件集中,找出所有类型名为“UIAButton”的子控件数组,接着在数组中获取第一 个子控件(:eq(0))的后面一个名为“UIAButton”的子控件。

TestUIDemo_ControlTree_Details1

2、[iOS]上,针对JavaScript UIA对象,iQuery给每个对象提供了iQuery查询扩展函数:

test("测试对UIAElement的扩展", function() {    
    var result = root.$("> [value >= 59%]");
    assert.Equals(1, result.length);
    root.logElementTree();

    result = root.segmentedControls()[0].$("> :button");
    assert.Equals(3, result.length);
});

上例演示了针对任意一个UIAElement对象,都有一个扩展的iQuery函数$(query)。

3、再来看看指定iQuery查询条件“selector”和查询起始的控件位置“context”的做法:

test("(*)匹配所有元素", function(){
    var query = "> *";
    var result = $(query, root.navigationBars()[0]);
    assert.Equals(2, result.length);
assert.Equals("UIAStaticText", type(result[1]));

    query = ">> UIAStaticText:not([name!='TestUIDemo'])";
    result = $(query, root);
    assert.Equals(1, result.length);
    assert.Equals("TestUIDemo", result[0].name());
});


上例中,“>> UIAStaticText:not([name!='TestUIDemo'])”的意思是从指定的上下文(context)控件root的所有子孙控 件集合里,首先过滤出类型名为UIAStaticText的控件列表,再在其中找出所有不满足name属性的值不是“TestUIDemo”的控件,如下 图所示:

TestUIDemo_ControlTree_Details2

从前面几个例子里可以看出,iQuery分为这几大部分:
以空格分隔的过滤条件默认是交集查询的方式,即后一个条件在前一个条件过滤后的控件集合里执行过滤操作。这一点跟jQuery的语法是不一致的,在jQuery里,空格分隔的条件是爷孙关系,即前一个条件在爷爷层过滤控件,再在结果控件的子孙控件中匹配空格后的条件。

子孙层次查询,通过“>”、“>>”等操作符指明过滤的层次。
注意:在iOS平台上,instrument下javascript的API在遍历控件树时非常慢,以本文的测试程序为例,从窗口层开始执行全遍历需要2分钟左右,因此除非特别有必要,不建议在iOS平台下使用“>>”操作符。

按照任意的控件类型名查询控件。
注意:在jQuery里,根据控件类型名的查询是在当前context控件的子孙控件集里查询的,由于前面描述的原因,iOS上子孙控件的遍 历操作非常慢,因此从代码执行速度方面的考虑,iQuery只在context控件这一层执行查询操作,如果要在子孙控件里过滤,必须使用“>”、 “>>”和“> num”操作符指明要查询的控件在控件树里的层次信息。

#id,按照控件的Id查询。
注意:按控件id查询默认是在当前context控件的子孙控件集里查询的,由于前面描述的原因,iOS上子孙控件的遍历操作非常慢,因此除非迫不得已,不建议使用。

伪类型,以冒号开头的类型都是伪类型。iQuery通过将多个平台共有的控件抽象成伪控件,便于对跨平台应用的测试,比如说,几乎所有的操作系统里都有文本框这个概念,因此使用“:text”这个伪类型就可以表达不同操作系统上的文本框了。

属性,根据控件自身的属性值过滤,属性值支持字符串的比较(如 [attr $= ‘value’] 指查询属性“attr”的值以字符串“value”结尾的控件),数字甚至的百分比的比较(如 [attr >= 59%] 指查询属性“attr”的值大于59%的控件)。

伪属性,跟伪类型类似,用来抽象不同平台控件共有的属性,例如表示控件位置的top、left、right、bottom、width和height之类的属性。伪属性支持用户扩展,即可以在测试用例里注册一个新的伪属性,通过提供的自定义过滤函数查询。

最后,希望iQuery能够简化你的自动化测试编写工作,如果有任何建议,请在iQuery的官方文档的评论栏(http://www.vowei.com/iquery-1.html)提出你的宝贵意见。

本文由知平软件 施懿民编写,请关注我们的微博

举报
红薯
发帖于5年前 0回/616阅
顶部