AirtestProject 【干货】如何生成高效、兼容性好的 Poco 定位脚本
此文章来源于项目官方公众号:“AirtestProject”
版权声明:允许转载,但转载必须保留原链接;请勿用作商业或者非法用途
1. 前言
很多新手同学在学习 Poco 测试框架的时候,会经常遇到一些关于控件定位脚本的问题。比如,上一秒还能正常运行的控件定位脚本,下一秒就报错找不到控件了;再比如,明明不同手机上装的都是同一款应用,但就是有些手机报找不到控件......
这一种种 “诡异” 的情况,都让我们百思不得其解。所以今天的推文内容,我们将详细地跟大家分享下在编写 Poco 定位脚本时,我们可以用到的一些实用技巧,超长干货,同学们一定要 mark 住哦!
2. 生成 Poco 定位脚本的多种方式
在了解 Poco 定位脚本的编写技巧之前,我们先来细细回顾一下,我们可以通过哪些方式来 “生成” 1 条 Poco 定位脚本。
1)单步录制 - 双击节点
在 AirtestIDE 连接上设备之后,打开待测应用,随后在 IDE 的 Poco 辅助窗中选择对应的 Poco 模式,等待 UI 树刷新出来:
利用检索按钮检索到目标控件之后,双击 UI 树上的该节点,IDE 即可帮助我们自动在脚本编辑窗里面自动生成 1 条控件定位脚本:
2)单步录制 - 右键选择 UI path code
同上,在 IDE 的 Poco 辅助窗刷新出控件树之后,单击选中我们的目标节点,然后单击鼠标右键,选择 UI path code
,IDE 的脚本编写窗口就会自动帮我们生成 1 条控件定位脚本:
3)自动录制
另外,IDE 还提供像录制 Airtest 脚本一样的,自动录制 Poco 脚本的功能:
单击 Poco 辅助窗的录制功能,然后随着我们对设备画面的操作,IDE 会自动在脚本编写窗口录制下来我们的 Poco 操作脚本。
4)手动编写 - 根据 3 种定位选择器
除了使用 IDE 给我们提供的各种录制方式之外,我们还可以根据各种控件定位规则,手动编写 Poco 定位脚本。
Poco 给我们提供了 3 种定位选择器,分别是:
- 基本选择器:根据控件的属性和属性值来进行定位,常见的比如 name 属性、text 属性等
- 相对选择器:根据控件之间的渲染层级关系来进行定位,常见的关系比如父子关系、兄弟关系等
- 空间顺序选择器:按照控件的空间排布顺序,从左到右,从上到下,添加索引值来进行控件定位
我们在定位脚本时,可以仅仅使用其中一种定位选择器,也可以混合使用多种定位选择器来编写控件的定位脚本,详细的介绍可以查看我们的往期推文 poco 的元素定位搞不定?速来看看这 3 个选择器 。
下面我们提供一些利用这 3 种选择器进行示例脚本:
# 使用基本选择器的poco定位脚本
poco(text="每日推荐")
# 使用相对选择器的poco定位脚本
poco("android.widget.LinearLayout").offspring("com.netease.cloudmusic:id/swipeToRefreshView").child("com.netease.cloudmusic:id/recyclerView")
# 使用控件顺序选择器的poco定位脚本
poco("android.widget.LinearLayout").offspring("com.netease.cloudmusic:id/swipeToRefreshView").child("com.netease.cloudmusic:id/recyclerView")[0]
5)手动编写 - 根据正则匹配表达式
除了上述 3 种定位选择器之外,我们还支持使用正则匹配表达式来匹配我们的 Poco 控件。
在部分情况下,使用正则匹配表达式来匹配 Poco 控件,会使得我们的定位脚本更加简洁省事。
这里简单列举几个使用正则表达式匹配控件的脚本:
# 匹配控件的name属性
poco(nameMatches="com.*?songInfo")
# 匹配控件的text属性
poco(textMatches=".*淘宝")
关于利用正则匹配表达式来匹配控件的详细内容,也可以参考我们的往期推文 真香系列!用正则表达式匹配 poco 控件,学会了秒杀各种定位选择器 。
其中我们需要记住的最重要的一点是:只要能够用 poco(xx=预期属性值)
来选择的控件,就可以用 poco(xxMatches=预期属性值的正则表达式)
来进行匹配定位。常见的如常 textMatches
、 nameMatches
和 typeMatches
等等。
3. 生成高效、兼容性好的 Poco 脚本技巧
那简单了解完 “生产” Poco 定位脚本的各种方式之后,我们再来聊一聊其中的一些技巧。
1)尽量不要完全依赖自动录制
尽管我们的 IDE 提供了自动录制 Poco 脚本的功能,但是我们还是希望同学们不要过于依赖自动录制出来的 Poco 脚本。
我们更建议大家在学习 Poco 脚本的初期使用这个功能,来更好的熟悉我们的 Poco 脚本长什么样子,把录制的脚本作为参考。
这是因为自动录制的 Poco 脚本,并不完全是正确的、或者是优秀的 Poco 脚本,有时候我们录制下来的 Poco 脚本并不能成功回放出来我们期望的效果,或者因为层级过于复杂导致运行效率很低。
举个例子:
poco(text="每日推荐").click()
poco("android.widget.LinearLayout").offspring("com.netease.cloudmusic:id/daily_rv").child("com.netease.cloudmusic:id/musicListItemContainer")[0].child("com.netease.cloudmusic:id/songItemVideoBtn").click()
poco("转到上一层级").click()
这 3 条是自动录制出来的 Poco 脚本,我们可以对每一条简单分析下:
① 第一条就是很标准的利用 text 属性进行定位的脚本,没什么疑问,只要 text 属性在当前页面是唯一的,那就没有很大的问题;
② 第二条就是非常典型的,录制出来的层级过于复杂的脚本,这里涉及了三四层的相对关系,还带有空间索引,很容易出现运行效率差,或者因为索引值变化而导致出现找不到控件的问题;这种定位脚本我们使用过程就需要慎重考虑了,最好更换成别的更加简洁清爽的定位方式;
③ 第三条是录制出来的一个返回上一个页面的 Poco 定位脚本,这种情况更好的方式是不使用 Poco 定位脚本,替换成 keyevent("BACK")
,更加简单而且稳定。
我们列举这个例子,就是为了说明,录制功能虽然很 “小白”,但是我们还可以将录制出来的 Poco 脚本优化成更加优秀的脚本,所以同学们不要过去依赖这个录制功能。
2)减少使用 UI path code 方式单步录制的脚本(效率低、易出错)
上文我们介绍了如何在 IDE 中右键单击 UI 树的控件,然后选择 UI path code 来生成 1 条控件定位脚本,但其实,我们并不是非常建议这种方式生成的定位脚本。
举个例子,我们以点击桌面上的网易云音乐图标为例,分别用右键 UI path code 的方式和双击节点的方式生成定位脚本,并分别单独运行查看效果:
poco("com.mumu.launcher:id/workspace").child("android.view.ViewGroup").child("android.view.ViewGroup").child("android.widget.TextView")[8].click()
poco(text="网易云音乐").click()
可以看到,UI path code 方式生成的脚本是以复杂的层级关系来定位的,并且包含空间索引,不如直接使用 text 属性来进行定位的脚本那么简洁,还更容易出错,所以非必要情况下,我们不那么建议使用这种方式生成定位脚本。
当然,右键 UI path code 方式生成的脚本并不一定都是会出错的脚本,这里仅列举了 1 个容易出错的例子,方便说明。
3)多使用控件的 text 之类的属性提高效率
我们刚才讲了很多次不建议使用复杂的层次关系(族谱)来进行定位,那么更加建议的方式是什么呢?其实就是使用元素的属性值来定位脚本。
举个例子,假设我们想要点击网易云音乐首页的 “每日推荐” 控件,利用文本属性编写定位脚本的话,将非常简洁,效率也会更高,不用管它复杂的层级关系以及空间索引顺序:
触类旁通,使用 1 个节点的某个属性值,不仅仅指 text 属性,还可以是 name 属性或者其它属性,只要它在当前页面是唯一的,那么我们就可以利用这个属性来定位到我们的控件;甚至借助节点的多个属性值来进行精准定位控件,都是可以的。我们非常建议大家多使用这种方式来编写我们的 Poco 定位脚本。
4)推荐使用正则表达式匹配控件
我们非常推荐同学们多使用正则表达式来匹配控件,特别是对于一些层次关系非常复杂的控件,使用正则表达式来匹配,会非常简洁高效。
举个例子,假设我们希望获取当前页面所有歌曲的详细介绍信息,如果使用之前介绍的定位方式,脚本可能如下:
可以看到,利用基本选择器和相对选择器写出来的定位脚本,看起来非常繁琐,而且我们还需要非常 精确地了解其中的层级关系 ,否则定位脚本就很容易出错。
那么我们试试换成正则表达式的定位方式:仔细观察 UI 树发现,这些歌曲信息的控件名都是一样的,所以只要我们写 1 个正则表达式,匹配到这一批相同的控件名,就相当于定位到了当前页面所有的歌曲信息控件,接下来就可以利用 poco 遍历,逐一获取控件的 text 属性了:
是不是非常简洁高效呢!
4. 小结
那今天的教程内容到这里就结束了,我们总共介绍了 5 种生产脚本的方式,以及 4 种编写 Poco 脚本的小技巧,通过下述的思维导图,可以帮我们快速了解整个文章的大致内容:
后续有更多的关于 Poco 脚本的编写技巧,我们还会持续跟大家进行分享,希望大家动动手指帮忙点个赞或者在看呗~
Airtest 官网:https://airtest.netease.com/
Airtest 教程官网:https://airtest.doc.io.netease.com/
搭建企业私有云服务:https://airlab.163.com/b2b
官方答疑 Q 群:654700783
呀~这么认真都看到这里啦,帮忙点击左下角的爱心,给我点个赞支持一下把,灰常感谢~