poco节点关系大公开!

此文章来源于项目官方公众号:"AirtestProject"

版权声明:允许转载,但转载必须保留原链接;请勿用作商业或者非法用途

一、前言

在自动化测试的实践中,我们发现许多同学在使用Poco框架进行控件定位时,对于节点之间的关系理解不够深入。那么本周让我们来详细讲解Poco框架中的child&children、offspring、sibling和parent等节点关系定位方法。

二、Poco定位节点的关系分析

2.1 child&children

从字面上看,可以很明显知道child与children表示的就是获取该节点下的子节点。如果是需要获取多个子节点,需要通过for去循环提取,不通过循环获取的话,默认都是提取第一个节点,但顺序编号从0开始。

其中child可以携带参数,可以获取指定的子节点,如:

erlang 复制代码
poco("android.widget.FrameLayout").child("android.widget.LinearLayout")

但children是不能携带参数的,是可以直接获取所有的子节点,但可以根据返回的子节点顺序进行指定,默认返回的是提取的第一个节点(顺序编号从0开始)如:

scss 复制代码
poco("android.widget.FrameLayout").children()[2]

2.2 offspring

offspring是获取该节点的子孙节点,若需要输出多个子孙节点,使用for循环去进行输出,默认输出为首个子孙节点。在使用过程中,如果不清楚自己所需节点的编号为多少,我们可以选择用for输出后,按照顺序编号进行选择使用。

scss 复制代码
poco("com.netease.cloudmusic:id/bannerContainer").offspring()

可以根据输出的顺序,结合下图,其中下述语句表达为"每日推荐"控件:

scss 复制代码
poco("com.netease.cloudmusic:id/portal_rv").offspring()[10]

也可以在offspring括号内指定自己所需要的子孙节点,如:

erlang 复制代码
poco("com.netease.cloudmusic:id/portal_rv").offspring("com.netease.cloudmusic:id/portalTitle")

上述语句同样表示为"每日推荐"控件。这样有个好处就是,当有多个相同name的控件但存在不同name的上层节点时,可以很好的区分每个控件。

2.3 sibling

siblings表示获取当前节点的兄弟节点,即与当前节点处于同一层级的其他节点。若需要输出多个兄弟节点,使用for循环进行输出,默认输出为首个兄弟节点。

scss 复制代码
poco("com.netease.cloudmusic:id/biFl").sibling()

如下图,可以看到该节点下返回的兄弟节点与UI树相匹配:

同样,sibling也是可以根据循环获取输出的顺序进行指定的,如:

scss 复制代码
poco("com.netease.cloudmusic:id/biFl").sibling()[3]

2.4 parent

在poco中,parent表示获取当前节点的父节点。如果需要获取整个节点集合的父节点,需要找到节点集合的第一个节点。 如果需要获取多层父节点,可以通过.parent()方法进行逐级获取。

例如,对于一个节点A,它的父节点是B,B的父节点是C,那么可以通过A.parent().parent()来获取到节点C。

scss 复制代码
poco("com.android.systemui:id/status_bar_contents").parent()

综上所述,如果需要获取该界面的所有节点,可以通过.parent() 或 .children() 等方法互相结合来获取其他层级中的所有节点,然后再通过遍历筛选出除了当前节点外的其他节点。

在开源群内,有一些同学也问过如何统计UI树某层或某控件的个数,我们可以通过上述的节点关系,结合python已有的len()函数,或使用for循环累加的方式去获取的。如:

scss 复制代码
#【利用子孙节点关系定位元素】统计输出热歌榜当前界面中歌曲数量
num=len(poco("com.netease.cloudmusic:id/musicInfoList").offspring(nameMatches="com.*?songName"))    
print("当前界面有{}首歌".format(num))

#【利用子节点关系定位元素】统计输出当前界面的热门节目单数量
num=0
for x in poco("CollectionView").child("UIA.Podcasts.ShelfItem.show"):
    print(x.child().child().get_name())
    num+=1

三、Android上的案例

了解完Poco节点关系的具体用法后,我们可以尝试在日常跑测中使用上节点关系,让我们来看一下在Android上的一个使用案例吧。

参考代码如下:

可以看到,我们通过节点关系可以获取到它的父节点、兄弟节点、子孙节点等,并可以对其进行点击、统计、输出信息等操作。

scss 复制代码
# -*- encoding=utf8 -*-
__author__ = "Airtest"

from airtest.core.api import *

auto_setup(__file__)

from poco.drivers.android.uiautomation import AndroidUiautomationPoco
poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)

#打开网易云音乐
start_app("com.netease.cloudmusic")
sleep(7.0)

#【利用子孙节点关系寻找元素】通过输出子孙节点去查找"发现"按钮
for i in poco("com.netease.cloudmusic:id/bottomNav").offspring(nameMatches="com.*?desc"):
    print(i.get_text())

#【利用子孙节点关系以及空间顺序定位元素】点击"发现"按钮
poco("com.netease.cloudmusic:id/bottomNav").offspring(nameMatches="com.*?desc")[1].click()
sleep(1.0)

#【通过兄弟节点关系定位元素】点击发现页中"精选"旁边的"排行榜"按键
poco("精选").sibling()[1].click()
sleep(1.0)

#点击热歌榜
poco(text="热歌榜").click()

#【利用子孙节点关系寻找元素】输出热歌榜中每首歌的名字
print("当前界面的热歌榜歌曲有:")
for i in poco("com.netease.cloudmusic:id/musicInfoList").offspring(nameMatches="com.*?songName"):
    print(i.get_text())
    
#【利用子孙节点关系定位元素】统计输出热歌榜当前界面中歌曲数量
num=len(poco("com.netease.cloudmusic:id/musicInfoList").offspring(nameMatches="com.*?songName"))    
print("当前界面有{}首歌".format(num))
    
#【利用子节点关系定位元素】输出目前播放器在播放的歌曲名
print("下方为正在播放的歌曲:")    
now_song = poco("com.netease.cloudmusic:id/minibar_song_container").child().children()   
print(now_song.get_text())

四、iOS上的案例

日常使用中可以发现,在iOS上获取对应的UI树控件比较困难,但是可以通过Poco节点关系的方法,更大程度地去寻找到自己想要获取的控件或ui树节点。

参考代码如下:

scss 复制代码
# -*- encoding=utf8 -*-
__author__ = "Airtest"

from airtest.core.api import *

auto_setup(__file__)
from poco.drivers.ios import iosPoco
poco = iosPoco()

#打开播客app
poco("播客").click()

#【利用子节点关系定位元素】输出该界面的信息,点击选择查看热门节目
for i in poco("CollectionView").child():
    print(i.get_name())

#【利用子节点关系结合子孙节点关系定位元素】点击进入热门节目界面 
poco("CollectionView").child("热门节目").offspring("查看全部").click()

#【利用子节点关系定位元素】输出当前界面的热门节目单
num=0
print("当前热门节目单有:")
for x in poco("CollectionView").child("UIA.Podcasts.ShelfItem.show"):
    print(x.child().child().get_name())
    num+=1

#【通过循环累计获取节点个数】输出当前界面的热门节目数量
print("当前界面有{}个节目".format(num))   

#【利用父节点关系结合子节点关系定位元素】点击播放键进入播放界面
poco("MiniPlayerArtworkVisible").parent().child()[2].child()[0].click()

#【利用兄弟节点关系定位元素】点击播放键进行播放
poco("倒回,15秒钟").sibling()[1].click()

五、小结

本周我们介绍了Poco节点关系:

1、child&children 获取子节点

2、offspring 获取子孙节点

3、sibling 获取兄弟节点

4、parent 获取父节点

通过深入理解child&children、offspring、sibling和parent这些节点关系,我们能够更加精确和高效地定位到UI树中的各个节点。

如果同学们在使用Poco进行自动化测试的过程中,遇到了问题,或者有任何想要深入了解的知识点,欢迎在群里告诉我们或者提交issue,也欢迎大家投稿。后续我们会带来更多精彩的有关Poco专题内容,请大家持续关注我们,敬请期待哦!


AirtestIDE下载:airtest.netease.com/
Airtest 教程官网:airtest.doc.io.netease.com/
搭建企业私有云服务:airlab.163.com/b2b

官方答疑 Q 群:526033840

相关推荐
千里马学框架3 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台3 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone3 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc3 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo3 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077003 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
茶底世界之下4 天前
为什么预览、录制、离线导出不能共享同一个背压策略?
ios·swift
AFinalStone4 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen4 天前
属性动画原理与高级动画实现
android·kotlin·canvas