原创: George555 公众号: 测试江湖路
如果这些内容对你有帮助,也可以打开微信扫一扫,加关注:
最近有很多朋友看了我上一篇写的【poco的元素操作及常用方法整理】,对于元素定位还是有很多疑问,今天就来一场真实场景的演练。
笔者个人觉得:在poco中用到的元素定位方式,比起Selenium中的8大定位方式,简直是不能再方便了(而且是那么的简单易上手),此篇就彻底扒开poco元素定位之谜。
一、场景示例
这里就用隔壁老王家族谱来进行场景演示:
图中这种树结构,与应用界面元素中的树结构方式类似。
下图为微信-发现页面的元素结构图:
二、场景示例应用
下面来对老王家族谱进行刨根问底。
1.如果要找到王大三这个人,怎么找?
A.直接根据王大三的名字找---->poco('王大三')
B.找王大爷的子孙中第5个---->poco('王大爷').offspring()对此进行遍历找到王大三
C.在王大二的兄弟中找王大三---->poco('王大二'),sibling()
D.在王大叔的儿子中找王大三---->poco('王大叔').child('王大三')
2.如果知道了王大三,要找王大叔这个人,怎么找?
A.找王大三的爸爸---->poco('王大三').parent()
B.找到王大三的爷爷-王大爷,在找王大爷的子孙中第1个儿子---->poco('王大三').parent().parent().offspring()对此进行遍历找到王大叔
3.如果只知道王大三名字的前两个字,怎么找王大三? (text用正则匹配)
A.poco(textMatches='^王大.') #这样就找到所有名字前2个字是王大的,然后再逐步分析那个是王大三,如果目标节点是只有1个王大三,则结果就是王大三了
三、真实案例应用 接下来针对微信来做些案例剖析
1.获取朋友圈节点,拿到相关属性值:
poco(text='朋友圈') 或
poco(text='朋友圈',name='android:id/title') 或
poco(text='朋友圈',type='android.widget.TextView')
注:见如下示例代码可知,定位中各种属性可以同时使用,避免节点重复提高定位准确率
print('===朋友圈text值:',poco(text='朋友圈').get_text())
print('===朋友圈节点的name值:',poco(text='朋友圈',name='android:id/title').attr('name'))
print('===朋友圈节点的pos值:',poco(text='朋友圈',type='android.widget.TextView').attr('pos'))
'''输出:===朋友圈text值:朋友圈
===朋友圈节点的name值:android:id/title
===朋友圈节点的pos值:[0.20416666666666666, 0.1421875]
'''
AirtestIDE上ui定位识别如下图:
2.根据朋友圈节点,去获取朋友圈左边的图标节点信息
先看下AirtestIDE上ui定位识别如下图:-> ahw则为左边图标的节点、title为朋友圈文字的节点
由图可知要根据朋友圈节点即name=android:id/title找到com.tencent.mm:id/ahw,则可以:
A.找到朋友圈节点 再往上的3层父节点的兄弟节点就可以了。
B.或者往上4层父节点的子孙节点,再遍历找到com.tencent.mm:id/ahw 就可以了。
A. 方法代码:
icon=poco(text="朋友圈").parent().parent().parent()
icon2=icon.sibling()
for i in icon:
print ('icon==',icon)
for i in icon2:
print ('朋友圈图标节点name值:{},size值: {}'.format(i.attr('name'),i.attr('size')))
输出:
icon==name:com.tencent.mm:id/lj,size:[0.7833333333333333, 0.07890625]
朋友圈图标节点name值:com.tencent.mm:id/ahw,size值: [0.059722222222222225, 0.03359375]
朋友圈图标节点name值:com.tencent.mm:id/amc,size值: [0.8833333333333333, 0.07890625]
朋友圈图标节点name值:com.tencent.mm:id/lj,size值: [0.7833333333333333, 0.07890625]
最后,从上面打印出来的顺序知道了com.tencent.mm:id/ahw再第1个,这样就获取到了这个节点了:
print ('=====',icon2[0].attr('name'))
print ('=====',icon2[0].attr('size'))
输出:
===== com.tencent.mm:id/ahw
===== [0.059722222222222225, 0.03359375]
B. 方法代码:
#下来演示下从里往外一层层剥皮对比看看:
代码:
poco(text="朋友圈").parent()
print ('朋友圈图标节点name值:{},size值: {}'.format(i.attr('name'),i.attr('size')))
输出:
朋友圈图标节点name值:android.widget.LinearLayout,size值: [0.6833333333333333, 0.0328125]
代码:
poco(text="朋友圈").parent().parent()
print ('朋友圈图标节点name值:{},size值: {}'.format(i.attr('name'),i.attr('size')))
输出:
朋友圈图标节点name值:android.widget.LinearLayout,size值: [0.6833333333333333, 0.07890625]
代码:
poco(text="朋友圈").parent().parent().parent()
print ('朋友圈图标节点name值:{},size值: {}'.format(i.attr('name'),i.attr('size')))
输出:
朋友圈图标节点name值:com.tencent.mm:id/lj,size值: [0.7833333333333333, 0.07890625]
代码:
poco(text="朋友圈").parent().parent().parent().parent()
print ('朋友圈图标节点name值:{},size值: {}'.format(i.attr('name'),i.attr('size')))
输出:
朋友圈图标节点name值:com.tencent.mm:id/amc,size值: [0.8833333333333333, 0.07890625]
经过4次处理终于获取到了com.tencent.mm:id/amc 这个节点,接下来找下这个节点的所有子孙节点:
代码:
icon=poco(text="朋友圈").parent().parent().parent().parent().offspring()
for i in icon:
print ('朋友圈图标节点name值:{},size值: {}'.format(i.attr('name'),i.attr('size')))
输出:
朋友圈图标节点name值:com.tencent.mm:id/ami,size值: [0.025, 0.0140625]
朋友圈图标节点name值:com.tencent.mm:id/ahw,size值: [0.059722222222222225, 0.03359375]
朋友圈图标节点name值:android:id/title,size值: [0.12916666666666668, 0.0328125]
朋友圈图标节点name值:android.widget.LinearLayout,size值: [0.6833333333333333, 0.07890625]
朋友圈图标节点name值:android.widget.LinearLayout,size值: [0.6833333333333333, 0.0328125]
朋友圈图标节点name值:com.tencent.mm:id/lj,size值: [0.7833333333333333, 0.07890625]
朋友圈图标节点name值:com.tencent.mm:id/amg,size值: [0.1, 0.05625]
朋友圈图标节点name值:com.tencent.mm:id/amh,size值: [0.08055555555555556, 0.0453125]
对于这个遍历顺序,配张图:
最后,从上面打印出来的顺序知道了com.tencent.mm:id/ahw在第2个,这样就获取到了这个节点了:
print ('=====',icon[1].attr('name'))
print ('=====',icon[1].attr('size'))
输出:
===== com.tencent.mm:id/ahw
===== [0.059722222222222225, 0.03359375]
【特别注意】:对于offspring()和sibling()查询子孙节点,兄弟节点的方式,获取多个子孙节点、兄弟节点的顺序,笔者尝试后发现是没有规律的,所以只能先遍历下,找到对应节点的索引,然后再去通过这个索引值去指定对应节点。(不知道是不是官方源码中一个潜在bug ^~^)
四、其他相关
1.经过一-三,知道了怎么找到元素了,那找到元素后有怎么获取元素的属性值呢?
poco(’节点名‘).attr('属性名')
2.怎么获取元素中text的值?
poco(’节点名‘).get_text() #当然这样用必须保证这个节点是有text属性的,否则会获取为空。
3.child和children都是提取子节点,区别是什么?
这个大家可以翻下源码,child是有参数name的,而children是没有参数的,这就可以区分对child是可以根据name来筛选某个子节点,对children无法筛选,结果有几个子节点就查出几个子节点。child和children都是可以提取多个子节点的,如果不去遍历的话,默认提取第一个子节点。
最后的说明:对于poco的元素查找,基本就这么多(父子关系、兄弟关系、子孙关系),文字写起来比较多,其实核心就是树结构的查询方式,如果你了解web页面定位中xpath的定位方式,就很容易理解这个了。
如果大家想问开头说的Selenium八大定位是什么,后续文章会针对这个做整理,请持续关注本公众号【测试江湖路】。
#####欢迎大家加群交流####
QQ:464314378
微信群请先加群主微信,群主会拉各位小伙伴进群,注意添加备注。