poco常用语法汇总
前言
Poco 是一款基于UI控件识别的自动化测试框架,目前支持Unity3D/cocos2dx-*/Android原生app/iOS原生app/微信小程序,也可以在其他引擎中自行接入poco-sdk来使用,原理:类似appium,基于UI控件搜索的自动化测试框架,定位目标控件,然后调用函数方法对目标控件进行操作。
使用Poco选择UI对象
基本选择器(Basic Selector)
在poco实例后加一对括号就可以进行UI选择了。选择器会遍历所有UI,将满足给定条件的UI都选出来并返回。
括号里的参数就是所给定的条件,用属性名值对表示,其中第一个参数固定表示 节点名 其余可选参数均表示节点的属性及预期的属性值。
# select by node name poco('bg_mission') # select by name and other properties poco('bg_mission', type='Button') poco(textMatches='^据点.*$', type='Button', enable=True)
相对选择器(Relative Selector)
直接用节点属性没法选出你所想要的UI时,还可以通过UI之间的渲染层级关系进行选择,例如父子关系、兄弟关系、祖先后代关系。
# select by direct child/offspring poco('main_node').child('list_item').offspring('item')
空间顺序选择器(Sequence Selector)
按照序号(顺序)进行选择总是按照空间排布顺序,先从左往右,再像之前那样一行一行从上到下,如下图中的数字标号,就是索引选择的序号。索引选择有个特例,一旦进行选择后,如果UI的位置发生了变化,那么下标序号仍然是按照选择的那一瞬间所确定的值。即,如果选择时1号UI现在去到了6号的位置,那么还是要用 poco(...)[1]
来访问,而不是6.如果选择了之后,某个UI消失了(从界面中移除或者隐藏了),那么如果再访问那个UI则可能会发生异常,其余的UI仍可继续访问。
items = poco('main_node').child('list_item').offspring('item') print(items[0].child('material_name').get_text()) print(items[1].child('material_name').get_text())
迭代一组对象(Iterate over a collection of objects)
下面代码片段展示如何迭代遍历一组UI
# traverse through every item items = poco('main_node').child('list_item').offspring('item') for item in items: item.child('icn_item')
读取属性(Get object properties)
mission_btn = poco('bg_mission') print(mission_btn.attr('type')) # 'Button' print(mission_btn.get_text()) # '据点支援' print(mission_btn.attr('text')) # '据点支援' equivalent to .get_text() print(mission_btn.exists()) # True/False, exists in the screen or not
操作UI对象(Object Proxy Related Operation)
点击(click)
点击默认点在 anchorPoint 上,每个UI都会有一个 anchorPoint ,也就是检视器(Inspector)中UI包围盒的那个红点,大部分情况下 anchorPoint 都在UI包围盒的正中央。如果想指定其他的点击位置,可以传一个参数到 click
方法中,这个参数是一个用list或tuple表示的2维向量,其 [x, y] 值分别表示相对于包围盒左上角的偏移量,左上角为 [0, 0]
,右下角为 [1, 1]
,具体用法请见 局部坐标系
。
下面的例子展示 click
的几种用法
poco('bg_mission').click() poco('bg_mission').click('center') poco('bg_mission').click([0.5, 0.5]) # equivalent to center poco('bg_mission').focus([0.5, 0.5]).click() # equivalent to above expression
滑动(swipe)
swipe操作同样是以 anchorPoint 为起点,如果你想改变起点请使用下面的 focus
方法,然后朝给定向量所代表的方向滑动,距离也就是向量的长度。关于向量的坐标如何表示可以参考 归一化坐标系
。
joystick = poco('movetouch_panel').child('point_img') joystick.swipe('up') joystick.swipe([0.2, -0.2]) # swipe sqrt(0.08) unit distance at 45 degree angle up-and-right joystick.swipe([0.2, -0.2], duration=0.5)
拖拽(drag)
与 swipe
不同的是, darg
是从一个UI拖到另一个UI,而 swipe
是将一个UI朝某个方向拖动。
下面例子展示如何使用 drag_to
方法
poco(text='突破芯片').drag_to(poco(text='岩石司康饼'))
局部定位(focus (local positioning))
所有UI相关的操作都默认以UI的 anchorPoint 为操作点,如果想自定义一个点那么可以使用 focus
方法。调用此方法将返回 新的 设置了默认 焦点 的UI,重复调用则以最后一次所调用的为准。focus
所使用的是局部坐标系,因此同样是UI包围盒的左上角为原点,x轴向右,y轴向下,并且包围盒长宽均为单位1。很显然中心点就是 [0.5, 0.5]
。下面的例子会展示一些常用的用法。
poco('bg_mission').focus('center').click() # click the center
将 focus
和 drag_to
结合使用还能产生卷动(scroll)的效果,下面例子展示了如何将一个列表向上卷动半页。
scrollView = poco(type='ScollView') scrollView.focus([0.5, 0.8]).drag_to(scrollView.focus([0.5, 0.2]))
等待出现(wait)
在给定时间内等待一个UI出现并返回这个UI,如果已经存在画面中了那就直接返回这个UI。 如果超时了还没有出现,同样也会返回,但是调用这个UI的操作时会报错。类似的操作还有,见 wait_for_appearance
poco('bg_mission').wait(5).click() # wait 5 seconds at most,click once the object appears poco('bg_mission').wait(5).exists() # wait 5 seconds at most,return Exists or Not Exists
全局操作(Global Operation)
在没有选定或指定UI的情况下也可以进行操作(模拟输入),也叫全局操作。
点击(click)
poco.click([0.5, 0.5]) # click the center of screen poco.long_click([0.5, 0.5], duration=3)
滑动(swipe)
# swipe from A to B point_a = [0.1, 0.1] center = [0.5, 0.5] poco.swipe(point_a, center) # swipe from A by given direction direction = [0.1, 0] poco.swipe(point_a, direction=direction)
截屏(snapshot)
截屏幕并以base64编码返回。截图的格式(png, jpg, …)由对应的sdk实现决定,大多数情况下是png。详见 ScreenInterface.getScreen
from base64 import b64decode b64img, fmt = poco.snapshot(width=720) open('screen.{}'.format(fmt), 'wb').write(b64decode(b64img))
异常处理(Exceptions)
PocoTargetTimeout
from poco.exceptions import PocoTargetTimeout try: poco('guide_panel', type='ImageView').wait_for_appearance() except PocoTargetTimeout: # bugs here as the panel not shown raise
PocoNoSuchNodeException
from poco.exceptions import PocoNoSuchNodeException img = poco('guide_panel', type='ImageView') try: if not img.exists(): img.click() except PocoNoSuchNodeException: # If attempt to operate inexistent nodes, an exception will be thrown pass