poco是网易自研的无需嵌入sdk。使用poco可以向appuim、selenium一样定位app上的元素对象位置。
poco安装有两种方式,第一种是直接网上搜索poco依赖包下载,然后使用python进行解压安装,这里不做介绍。另外一种是直接使用pip安装。
在命令行中使用指令:pip install pocoui进行安装。
等待安装完后使用pip list命令查看是否安装成功,如下,pip list指令下显示有pocoui了,版本是目前的最新版本。
poco的使用前还需要在手机上安装pocoserver,一般情况下在airtest连接手机的时候会自动安装pocoserver这个app,但是有些奇葩手机就没能安装,那么这个时候就要手动进行安装,可以使用手机助手安装,当然这里我使用的是adb shell指令安装的,使用adb指令:adb shell install apk路径。
1、启用poco。在Poco辅助窗口下,点击展开下拉菜单,然后选择Android (如果是iOS就选iOS),此时会自动启动pocosdk了,在窗口下会显示app当前界面的所有元素对象的活动名字(activity),同时在代码区域中会自动导入红色框的两行代码。这两行代码如无特殊情况请不要删除。这两行代码的功能是导入AndroidUIautomationPoco并且实例化poco。实例化后的poco可供后面代码直接使用。
2、poco元素对象定位
在编写代码之前要先定好好元素对象的位置在辅助窗口的那个地方,下图箭头按钮是开启实时显示元素对象的结构位置,我们只需要在鼠标标移到都某个UI上面,左边的元素结构就会自动显示到该UI的结构位置处,能够快速定位到具体的UI结构位置。
最右边的按钮是自动定位且记录功能按钮,也能够实时显示元素UI的位置,如果我们点击某UI时,就会自动在代码去生成对应的代码。不过不推荐此种方式,原因后面说明。
同时也可以在手机中鼠标置于某UI上,然后右击可以选择定位该UI的元素对象位置。
3、双击poco辅助窗下的具体元素,在代码中就会自动生成poco代码。我们只需要添加具体的操作即可。比如我们要定位到相册这个元素上,然后进行点击操作,所以可以这样操作。
在log查看窗口中会显示我们选中的元素具体信息,我们主要关注的是name、enable、touchable这几个属性即可,name用来作poco定位,需要留意的一点是,要注意查看上下几个同级的元素的name是否相同,如果是相同的话,name就不可以用来定位,因为多个名字poco不知要找那个(可以理解为同班级有俩张三,点名时不知道是叫那个)。enable值一般要为true才可以,说明这个元素对象是可用的。touchable也要为true,说明这个ui是可以点击的,否则这个UI是不可以点击的。一般情况是点击、输入等操作的话要为true,如果用来作判定比较的则不要求是true。
说明:以上这几点是poco的使用基础,熟悉并灵活使用poco定位对于用例的编写有很大的帮助。
这里使用poco定位,以企业微信作为例子编写一下实例作为用例例子。
1、启动app
启动app使用的方法是start_app()方法。该方法在airtest.core.api.py下的方法。方法的参数是包名,activity名。air的代码如下:
启动的效果如下:
2、启动‘日程’
首先定位到到日程的UI树位置是com.tencent.wework:id/afp,这里我作一个判定,先判定元素在不在,只有元素存在的时候才进行点击操作。具体的代码实现如下所示:
最后的运行效果如下所示:
通过如上的几个步骤,就能够使用poco进行UI元素定位测试了。下面说下poco其他常规操作。
要使用poco的操作,首先要实例化poco对象。声明poco对象的方法是:
poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)
通过上面这句话,就实例化了poco对象。可以使用poco封装好了的操作了。poco的操作方法放在poco\pocofw.py里面。
当实例化了poco后,在poco后面添加“.”后,会弹出可以调用的操作,操作有数十种,主要有等待、获取\设置文本信息、点击(单击\双击\长按等)、截图、滑动等常规操作。
这里介绍poco对象的几个常用的操作方法:
poco().wait_for_any(self, objects, timeout=120):
等待超时之前显示给定的UI,最后返回第一个出现的UI。每个UI都会有一个特定的时间轮询。第一个参数objects是一个可以迭代的UI对象,第二个参数是超时阈值,数值是float类型,默认时间是120秒。
poco().wait_for_all(self, objects, timeout=120):
等待所有的UI显示,如果没有显示出来在超时。同时所有的UI都会有个定期进行轮询。第一个参数objects是一个可以迭代的UI对象,第二个参数是超时阈值,数值是float类型,默认时间是120秒。
poco().wait_stable()
睡眠固定的秒数,以等待UI变得稳定(稳定)。无需手动调用此方法。需要时会自动调用它。
poco().click()
在给定坐标下点击设备屏幕
poco().long_click(self, pos, duration=2.0)
但在给定的时间间隔内按屏幕,然后释放。第一个参数是坐标位置,第二个参数是长按的时间。
poco().scroll(self, direction='vertical', percent=0.6, duration=2.0)
屏幕滚动,第一个参数滚动方向:水平\垂直,第二个参数是根据方向滚动距离占整个屏幕高度或宽度的百分比,第三个参数是执行操作的时间间隔。
poco().snapshot(self, width=720)
从目标设备获取屏幕截图。支持的输出格式(png,jpg等)取决于代理程序的实现。
airtest的其他常用api操作方法:
airtest的核心操作在core下的api.py下。api.py几乎封装了所有的操作,这里介绍下常用的操作方法。
这些操作都是api里面封装好了的,我们可以直接调用,要想调用一个函数,我们需要知道函数的名字与参数。如果参数传入的数量不对的话,那么会报TypeError的错误。
install(filepath, **kwargs):
安装app应用,第一个参数是app的路径名,**kwargs是可变参数,如无特殊情况,可以不需要。下面是install的使用例子:
install(filepath='xxx/xxx.apk') # 安装应用
uninstall(package):
卸载app,参数是app的包名。例子:uninstall('包名')
wake():
唤醒连接的手机。
home():
设置连接的手机返回home界面。
例子:
touch(v, times=1, **kwargs):
触摸设备屏幕,参数v是图片名字或者需要触摸屏幕的坐标,times参数是触摸次数,默认次数是1,**kwarges是平台特殊参数。return:返回被点击的位置。
例子:
double_click(v):
双击,参数v是图片名字或者需要触摸屏幕的坐标,最后返回点击的图片或者位置。
swipe(v1, v2=None, vector=None, **kwargs):
滑动,在设备上执行滑动操作。参数v1表示开始坐标或者图片,参数v2表示结束坐标或者结束的图片,参数vector表示矢量坐标,或者滑动坐标的百分比,比如(0.5,0.5)
例子:
pinch(in_or_out='in', center=None, percent=0.5):
在屏幕上执行缩放操作,参数in_or_out表示要进行的是缩放还是放大,默认是in,表示缩放,out表示放大,只能枚举这两个值。center参数表示缩放的中心,默认是None,表示屏幕中心,如果是其他地方的话,则使用(x,y)来表示缩放的中心坐标。percent缩放操作的缩放比,默认是0.5,表示缩放一倍。
text(text, enter=True, **kwargs):
输入文本信息,注意,这个输入的UI必须是激活状态的,否则无法输入,例如网易靓号界面在有登录弹出的时候,后面的搜索输入框是非激活状态,所以是无法输入消息的。参数text表示输入的内容,参数enter表示回车键是否除非事件,默认是True。
sleep(secs=1.0):
睡眠,默认执行睡眠事件1s。
wait(v, timeout=None, interval=0.5, intervalfunc=None):
在设定时间内等等匹配目标图片,如果能匹配到目标图片,则返回目标坐标,如果等待超时,引发TargetNotFoundError错误。参数v表示目标图片,参数timeout表示超时时间,intarval表示每次匹配的时间间隔。intervalfunc 表示在每次未成功尝试找到相应匹配项后调用,默认是None。
exists(v):
检查屏幕上的目标是存在。参数v表示目标图片、文本。如果没有找到,则返回false,否则返回找到的坐标。
find_all(v):
检查屏幕上所有的目标。参数v表示目标图片,文本。结果返回一个所有的匹配结果坐标的列表。
assert_exists(v, msg=""):
断言目标存在。参数v表示断言的目标,msg表示说明信息,这个信息会记录到报告中。如果断言失败则会报AssertionError错误。如果断言成功,则返回目标坐标。
assert_not_exists(v, msg=""):
断言目标不存在。参数v表示断言目标,msg表示说明信息,这个信息会记录到报告中。如果断言失败则会报AssertionError错误。
assert_equal(first, second, msg=""):
断言两个值相等。first表示第一个值,second表示第二个值。msg表示说明信息,这个信息会记录到报告中。如果断言失败则会报AssertionError错误。返回值无。
assert_not_equal(first, second, msg=""):
断言两个值不相等。first表示第一个值,second表示第二个值。msg表示说明信息,这个信息会记录到报告中。如果断言失败则会报AssertionError错误。返回值无。