iQuery是一个通用的跨平台的控件查询类库,其语法类似jQuery,但你可以在iOS、Android、selenium、甚至是桌面GUI程序上使用它。在iQuery之前,要在界面中查询一个控件,特别是自动化测试用例程序中,是比较麻烦的事情,而iQuery不仅可以用一段简洁的文本精准定位控件,还为使用同一个查询语句执行跨平台控件查询提供可能。

继上周发布iQuery iOS版发布之后,我们再接再厉完成Android版的开发,你可以在Android应用里使用iQuery批量处理和操作界面控件,有兴趣的朋友可以在这里下载:

https://github.com/vowei/iQuery/downloads

源码位置:
https://github.com/vowei/iQuery

要在Android程序以及Android自动化测试程序中使用iQuery,你需要引入下面几个包:
antlr-runtime-3.4.jar:用于词法解析。
iQA.Runtime.jar:iQuery语法解析主程序包。
iQA.Runtime.Instrument.jar:iQuery android插件。

如果你需要编写android instrument的UI自动化测试用例的话,还需要在测试用例工程里添加:
robotium-solo-3.1.jar:用于抓取android UI控件的类库。

运行iQuery所需要的依赖包都可以在下面这个地方下载:
https://github.com/vowei/iQuery/tree/master/java/lib

下面逐步介绍在eclipse的android自动化UI测试工程中使用iQuery的方法:

  • 首先创建一个android自动化测试工程,并在AndroidManifest.xml里指明要测试的Android程序的package名和应用的主Activity名。

    <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="cc.iqa.studio.demo.test" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" /> <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="cc.iqa.studio.demo" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <uses-library android:name="android.test.runner" /> </application> </manifest> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
  • 将antlr和robotium的依赖包加入Build Path:
    无标题
  • 新建一个类(测试用例或者其它都可以),在源文件里加入以下几个命名空间:
    import org.antlr.runtime.*; import cc.iqa.iquery.*; import cc.iqa.iquery.android.*; .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
    上面,org.antlr.runtime用于引入词法解析的一些类(可选引用);cc.iqa.iquery用于引入iQuery for Java的主程序;而cc.iqa.iquery.android则用于引入iQuery android插件的相关类型。
  • 如果你是编写自动化的Instrument测试用例,可能还需要引入下面的命名空间:
    import com.jayway.android.robotium.solo.*; .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
    com.jayway.android.robotium.solo是用来引入基于Instrument的UI自动化的类库。
  • 使用iQuery.query静态函数从一个控件开始执行iQuery查询,iQuery的语法说明请参见文章类jQuery selector的控件查询iQuery开源类库介绍
    List<SoloTreeNode> result = iQuery.query( new SoloTreeNode(_solo.getCurrentViews().get(0)), "LinearLayout &gt;&gt; TextView [mText = 'Down Under']"); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
  • parser.query返回的结果即是满足第5步中iQuery过滤条件的控件集合:
    Assert.assertEquals(2, result.size()); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
  • 完整的测试用例代码如下:
    public void test简化后的API() throws Exception { List<SoloTreeNode> result = iQuery.query( new SoloTreeNode(_solo.getCurrentViews().get(0)), "LinearLayout &gt;&gt; TextView [mText = 'Down Under']"); Assert.assertEquals(2, r1.size()); }.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

  • 如果有语法错误的话,iQuery.query会抛出一个iQueryParseException异常,捕捉该异常,调用其getErrors函数获取语法错误的详细描述。
    e.getErrors(); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
  • 在eclipse里右键单击测试工程,选择Run As -&gt; Android JUnit Test执行测试用例:

    无标题
  • 更详细的例子,请参看源码里附带的测试用Android工程和其相关的测试用例。

测试用android工程:https://github.com/vowei/iQuery/tree/master/java/Test/multiplatformdemoproject

相关测试用例:https://github.com/vowei/iQuery/tree/master/java/Test/iQA.Sample.multiplatformdemoprojecttest

无论是iQuery iOS版还是iQuery Android版本都可扩展的,后面将会介绍扩展iQuery的方法。