python-自动化Airtest-3IDE poco介绍

python-自动化Airtest-3IDE poco介绍

一 : AirTest Poco 介绍

1> Poco 理解

Airtest:基于Python的、跨平台的UI自动化测试框架,基于图像识别原理,适用于游戏和App。

Poco:基于UI控件搜索的自动化测试框架,其核心优势是除了对Android、IOS之外,对游戏也是支持的,同时也支持微信小程序、微信小游戏和H5应用

部件优点
AirTest简单直接、兼容各种环境、无需嵌入代码
Poco控件识别更加准确、界面迭代影响小

2> Poco 安装

在python中要通过pip安装

pip install pocoui

在Airtest IDE 环境自带poco库

AirtestIDE\poco

3> Poco import

导入Poco 库

from poco.drivers.android.uiautomation import AndroidUiautomationPoco

实例化

poco = AndroidUiautomationPoco(use_airtest_input=True,screenshot_each_action=False)

4> AirTest IDE Poco 介绍

在IDE 窗口上选择 Poco Assistant ;Poco 辅助窗口便在界面上显示
勾选需要链接设备类型;
在这里插入图片描述
这里选择android ,按照提示导入配置,及import 相关库和实例化Poco;
第一次链接设备安装 pocoservices apk完成界面即可获取到设备上的UI元素信息;
在这里插入图片描述
即在python 还是ide上可运行调试实现效果
demo

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

# script content
print("start...")
poco(text="微信").long_click()

二: Poco 语法

1> Poco 获取信息

1. poco.adb_client

链接指定设备

from airtest.core.android import Android
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
dev1 = Android("27QGL20828000064")
poco = AndroidUiautomationPoco(dev1, screenshot_each_action=False)

链接设备默认

from airtest.core.api import *
from airtest.cli.parser import cli_setup
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)
class AndroidUiautomationPoco(Poco)
ef __init__(self, device=None, using_proxy=True, force_restart=False, use_airtest_input=False, **options):
        # 加这个参数为了不在最新的pocounit方案中每步都截图
        self.screenshot_each_action = True
        if options.get('screenshot_each_action') is False:
            self.screenshot_each_action = False

        self.device = device or current_device()
        if not self.device:
            self.device = connect_device("Android:///")

        self.adb_client = self.device.adb

有此处看adb_client 是当前链接设备,这里仍可调用许多方法;一般我们都会适用Poco直接调用方法
在这里插入图片描述
例如:
1, 获取当前设备号信息

print(poco.adb_client.devices())
========================
[('27QGL20828000064', 'device')]


2, adb.exe 路径信息
print(poco.adb_client.adb_path)
========================
D:\python373\lib\site-packages\airtest\core\android\static\adb\windows\adb.exe


3, 当前cpu 频率
print(poco.adb_client.get_cpufreq()
=========================
1.4GHz


4, ip 信息
print(poco.adb_client.get_ip_address())
=============================
192.168.16.104

5, 列出安装的apk
print(poco.adb_client.list_app())
============================
['com.github.uiautomator', 'com.android.cts.priv.ctsshim', 'com.huawei.camera', 'com.google.android.ext.services', 'com.huawei.android.launcher', ........

6, 获取屏幕的分辨率

# 获取屏幕当前的分辨率
w,h=device().get_current_resolution()
print(w,h)
#获取手机分辨率
w,h=poco.get_screen_size()
print(w,h)

7,正则表达式定位元素
nameMatches & textMatches

# 获取元素name属性 get_name()
print(poco(text='无线和网络').get_name() )
# 模糊匹配查询
print(poco(textMatches='.*?网络').get_name() )
=======================
	android:id/title

8, 组合获取元素信息
获取信息:
获取位置:get_position()----》[0.25972222222222224, 0.27152777777777776]
获取元素边缘信息:get_bounds()-----》[0.25729166666666664, 0.36388888888888893, 0.2857638888888889, 0.15555555555555556]
获取元素name: get_name()---->android:id/title
获取元素text: get_text()----> 无线和网络
获取元素size: get_size()---->[0.20833333333333334, 0.02847222222222222]

2. poco.agent

 class Poco(PocoAccelerationMixin):
 ...........
 @property
    def agent(self):
        """
        Readonly property to access poco agent instance. See :py:class:`poco.agent.PocoAgent` for more details.

        Returns:
            :py:class:`poco.agent.PocoAgent`: poco agent instance
        """

        return self._agent

返回:
py:类:“poco.agent。 PocoAgent: poco代理实例

print(poco.agent.screen.getPortSize())
print(poco.get_screen_size())
=========================
[720, 1440] # 屏幕分辨率

3. poco.device

poco.device.list_app() # 列出apk名
poco.device.get_ip_address() #获取ip 地址

4. poco.attr

例如:获取如下demo 信息;
获取参数:
visible:用户是否可见 ,返回布尔值;
text : 返回UI元素的字符串值
type:返回远程运行时UI元素的类型名
pos: 返回UI元素的位置
size:返回尺寸百分比[宽度,高度],根据屏幕显示0~1
name:返回UI元素的名称
:返回SDK实现的其他属性

icon=poco(text="无线和网络")

print('UI元素的名称               {}'.format(icon.attr('name')))
print('用户是否可见               {}'.format(icon.attr('visible')))
print('UI元素的字符串值        {}'.format(icon.attr('text')))
print('运行时UI元素的类型名 {}'.format(icon.attr('type')))
print('UI元素的位置               {}'.format(icon.attr('pos')))
print('尺寸百分比[宽度,高度] {}'.format(icon.attr('size')))
print('其他属性信息               {}'.format(icon.attr('...')))
=======================================
UI元素的名称          android:id/title
用户是否可见          True
UI元素的字符串值      无线和网络
运行时UI元素的类型名  android.widget.TextView
UI元素的位置          [0.25972222222222224, 0.27152777777777776]
尺寸百分比[宽度,高度] [0.20833333333333334, 0.02847222222222222]
其他信息              None

后面可以对返回信息进行处理:
demo

w,h=device().get_current_resolution()#获取手机分辨率
icon=poco(text=“无线和网络”)
print(icon.attr(‘pos’))
x = int(icon.attr(‘pos’)[0]*w)
y = int(icon.attr(‘pos’)[1]*h)
print(x,y)
touch([x,y])

===================
[0.25972222222222224, 0.27152777777777776]
187 390
可以处理当前设备上坐标信息


在这里插入图片描述

2> Poco 模拟操作

1. poco.click()

在上节已经做介绍,这里可以对UI元素进行精确的锁定
poco.click()

if poco(text=’允许’).exists:
poco(text=’允许’).click()

2. poco.long_click()

参数:
pos: 按下坐标
duration 按下时间

def long_click(self, pos, duration=2.0):

下面这里可以对UI元素进行精确的锁定

poco(text="微信").long_click()
poco(text="设置").long_click(duration=3)

3. poco.scroll()

参数:滚动方向vertical &horizontal
percent: 滑动百分比
duration = 滑动时间float格式duration =3.0

def scroll(self, direction='vertical', percent=0.6, duration=2.0)

对屏幕的滚动控制

poco.scroll(direction='horizontal', duration=2,percent=0.8) #向左水平滑动

其实scroll 也是 通过swipe 来实现的操作

start = [0.5, 0.5]
        half_distance = percent / 2
        if direction == 'vertical':
            start[1] += half_distance
            direction = [0, -percent]
        else:
            start[0] += half_distance
            direction = [-percent, 0]

        return self.swipe(start, direction=direction, duration=duration)

4. poco.swipe()

参数:
direction : 方向,“上”,“下”,“左”,“右”-‘up’, ‘down’, ‘left’, ‘right’;
duration :操作执行的时间间隔
Raises: 当找不到元素时,会报错,raise PocoNoSuchNodeException(self)

def swipe(self, direction, focus=None, duration=0.5):
.........
 ret = self.poco.swipe(origin, direction=dir_vec, duration=duration)
        self.poco.post_action('swipe', self, (origin, dir_vec))
        return ret
poco(text="显示").swipe('up')
poco(text="显示").swipe('down')
poco(text="设置").swipe('left')

5. poco.drag_to()

#把“设置”元素拖动到“ATX”元素上(拖拽)
参数:
target :参数的目标,
duration :操作执行的时间间隔
Raises: 当找不到元素时,会报错,raise PocoNoSuchNodeException(self)

def drag_to(self, target, duration=2.0)
poco(text='设置').drag_to(poco(text='ATX'),duration=3.0)

6. poco.start_gesture()

建序列化的手势动作
这里实现效果要比drag_to 好;
注意::总是在当前UI对象的位置开始触降

from airtest.core.api import *
from airtest.cli.parser import cli_setup
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)

ui11=poco(text="设置")
ui12=poco(text="手电筒")
ui13=poco(text="服务")
ui11.start_gesture().hold(1).to(ui12).hold(1).to(ui13).hold(1).up()

7. swipe_along()

调用 :touch_proxy.swipe_along()
建序列化的手势动作 作用和drag_to 、start_gesture一致;其对以上补充,可传参坐标list 进行制作滑动 手势;
参数:
coordinates_list:坐标列表,例如:[[250, 500],[300, 500],[300, 700],[600,700 ]]
duration :两个坐标间间隔时间
steps:执行每2个点之间的运行步数;当 解锁九宫格每一步没必要再拆分,所以steps设为1
可通过实际情况对参数传参控制时间间隔等信息;

    def swipe_along(self, coordinates_list, duration=0.8, steps=5):
        pos_list = [self.ori_transformer(xy) for xy in coordinates_list]
        self.base_touch.swipe_along(pos_list, duration=duration, steps=steps)
        

demo

from airtest.core.api import *
dev = device()
dev.touch_proxy.swipe_along([[250, 500],[300, 500],[300, 700],[600,700 ]], duration=3, steps=3)

8. pinch()

上章对此功能在airtest做了解释,这里来说下的是poco 功能pinch他同样两指操作的
双指操作
poco(“无线和网络”).pinch()

def pinch(self, direction='in', percent=0.6, duration=2.0, dead_zone=0.1):
direction:缩放方向,只有"in"或"out"。 "in"表示挤压,"out"表示扩张  
percent:从UI的边界压缩范围或扩大范围  
duration:操作执行的时间间隔  obj: ' float 
dead_zone:收缩内圆半径。 不应该大于' percent ' ' 

实现双指操作的还有如下touch_proxy.two_finger_swipe()

参数:
tuple_from_xy:开始坐标
tuple_to_xy:结束坐标
duration:时间间隔,默认0.8秒
steps:执行步数,默认5
offset:第二根手指偏移量,默认(0, 50)
其具体步骤:
swipe_events:滑动事件列表分别加入两根手指的按下事件;向滑动事件列表依次加入等待事件、两根手指的分段移动事件;追加两个手指的抬起事件
self.perform(swipe_events):将滑动事件列表中的每个事件依次执行

    def two_finger_swipe(self, tuple_from_xy, tuple_to_xy, duration=0.8, steps=5, offset=(0, 50)):
        tuple_from_xy = self.ori_transformer(tuple_from_xy)
        tuple_to_xy = self.ori_transformer(tuple_to_xy)
        self.base_touch.two_finger_swipe(tuple_from_xy, tuple_to_xy, duration=duration, steps=steps, offset=offset)

demo

from airtest.core.api import *
dev = device()
# 画两条竖向平行线 - 从[250, 550]到[250, 700],持续10秒,分5步,第2根手指偏移量(200,0)
dev.touch_proxy.two_finger_swipe([250, 550],[250, 700], duration=10, steps=5, offset=(200, 0))
#画两条横向平行线 - 从[150, 1000]到[700, 1000],其余参数全部用默认
dev.touch_proxy.two_finger_swipe([150, 1000],[700, 1000])

9. focus().click()

点击操作

poco(text='无线和网络').focus('center').click()  # click the center

10. focus().drag_to()

scroll 操作
将 focus 和 drag_to 结合使用还能产生卷动(scroll)的效果
实现效果是局部的,是在poco(text=‘无线和网络’) 基础上移动相对图标高度的y值;
在这里插入图片描述

scrollView = poco(text='无线和网络')
scrollView.focus([0.5, 0.8]).drag_to(scrollView.focus([0.5, 0.1]))

注意:
如果实现大面积滑动时,就要选择元素的区域H足够高即如下;

scrollView = poco(name='android.widget.FrameLayout')
scrollView.focus([0.5, 0.8]).drag_to(scrollView.focus([0.5, 0.1]))

在这里插入图片描述

11. poco.pan()

平移
此功能未实现,可根据自己需求重新用swipe 封装使用

    def pan(self, direction, duration=2.0):
        raise NotImplementedError

3> 判断UI元素出现

1. 等待UI元素出现

poco等待UI元素的方式有三种:等待一个元素,等待多个元素,等待任一元素

poco.wait_for_all()
poco.wait_for_any()
poco.wait_stable()
#定位三个元素
ele1 = poco(text=“QQ”)
ele2 = poco(text=“QQ音乐”)
ele3 = poco(text=“微信”)
等待一个元素出现:ele1.wait_for_appearance(timeout=10)
等待多个元素都出现:poco.wait_for_all([ele1,ele2,ele3])
等待任一元素出现:poco.wait_for_any([ele1,ele2,ele3])

2. poco.wait_for_appearance()

poco阻塞并等待 wait_for_appearance
参数:
timeout :默认等待120s;阻塞并等待,直到UI元素在给定的超时内出现
PocoTargetTimeout:当超时

def wait_for_appearance(self, timeout=120)

eg:

poco(text='设置').wait_for_appearance()

3. 找不到元素就判断失败

result=poco(text="无线和网络").wait(5).exists()
print(result)
====================
True

4> 获取UI信息

通过Airtest 复制ui_path code 可以准确获取text 对应元素;

for pname in poco("android.widget.FrameLayout").offspring("com.android.settings:id/content_frame").offspring("com.android.settings:id/main_content").offspring("com.android.settings:id/dashboard_container").child("com.android.settings:id/dashboard_tile")[2].offspring("android:id/title"):

    print(pname.get_text())

1. 相对选择器

直接查询其节点及子节点信息
offspring:包括直接子元素(ren)的子代

si = poco("android.widget.FrameLayout").offspring("com.android.settings:id/drawer_layout").attr('size')
print(si)
=====================================================
[1, 0.9430555555555555]
si = poco("android.widget.FrameLayout").offspring("com.android.settings:id/drawer_layout").children()
for i in si:
    print(i.attr('name'))
    ===============
    com.android.settings:id/content_parent
com.android.settings:id/content_parent

在这里插入图片描述

2. 获取父节点、子节点

获取home界面图标text 信息,无需在乎父节点上面是是什么,只需要能区分别的父节点UI元素即可;
在这里插入图片描述

data = poco("com.huawei.android.launcher:id/workspace_screen").child("android.view.ViewGroup").children()
for each in data:
    print(each.get_text())
    ========================
    服务
主题
CHH_pro
Yosemite
手电筒
ATX
时钟
设置
PocoService
Appium Settings
暴风影音
acount_app

3. 在子节点下-返回上级或多级父节点

获取text = ‘无线和网络’ 即0 节点的父节;
其父节点为1,2,3;android:id/icon;android.widget.RelativeLayout;com.android.settings:id/arrow
在往上为1,2,3 父节点: 4 -com.android.settings:id/dashboard_tile
![在这里插入图片描述](https://img-blog.csdnimg.cn/446deb2c50074ff28c7ae55cc2c05aee.png

demo

icon=poco(text="无线和网络").parent()
icon2=icon.sibling()
for i in icon2:
    print('设置图标节点name值:{},size值: {}'.format(i.attr('name'), i.attr('size')))
    ==========================================
    设置图标节点name值:android:id/icon,size值: [0.06666666666666667, 0.03333333333333333]
设置图标节点name值:com.android.settings:id/dashboard_tile,size值: [1, 0.07847222222222222]
设置图标节点name值:android.widget.RelativeLayout,size值: [0.7555555555555555, 0.07847222222222222]
设置图标节点name值:com.android.settings:id/arrow,size值: [0.044444444444444446, 0.03333333333333333]

size: 其中size 返回的是占据屏幕宽度、高度的百分比; 例如:[1, 0.07847222222222222],元素占据整个屏幕宽和高的0.07847222222222222;

注意:
如果要获取更上层父节点的话,需要在对象后添加继续添加parent()参数;相对与上面demo ;
寻找0节点的父节点;

icon=poco(text="无线和网络").parent().parent()
========================================
设置图标节点name值:com.android.settings:id/search_view_container,size值: [1, 0.05555555555555555]
设置图标节点name值:com.android.settings:id/dashboard_tile,size值: [1, 0.07847222222222222]
设置图标节点name值:com.android.settings:id/category,size值: [1, 0.011111111111111112]
设置图标节点name值:com.android.settings:id/dashboard_tile,size值: [1, 0.07847222222222222]
设置图标节点name值:com.android.settings:id/dashboard_tile,size值: [1, 0.07847222222222222]
设置图标节点name值:com.android.settings:id/dashboard_tile,size值: [1, 0.07847222222222222]
设置图标节点name值:com.android.settings:id/dashboard_tile,size值: [1, 0.07847222222222222]
设置图标节点name值:com.android.settings:id/dashboard_container,size值: [1, 0.8430555555555556]
设置图标节点name值:com.android.settings:id/dashboard_tile,size值: [1, 0.07847222222222222]
设置图标节点name值:com.android.settings:id/dashboard_tile,size值: [1, 0.07847222222222222]
设置图标节点name值:com.android.settings:id/dashboard_tile,size值: [1, 0.07847222222222222]
设置图标节点name值:com.android.settings:id/dashboard_tile,size值: [1, 0.07847222222222222]
设置图标节点name值:com.android.settings:id/dashboard_tile,size值: [1, 0.07013888888888889]

上两级父节点:com.android.settings:id/** 1,2 部分
上三级父节点:om.android.settings:id/dashboard_container 3部分
在这里插入图片描述

4. 空间顺序选择

child 当前节点的子元素

name_list=list(poco("android.view.ViewGroup").child())
print(len(name_list))
for i in range(len(name_list)):
    print(poco("android.view.ViewGroup").child()[i])
    print(poco("android.view.ViewGroup").child()[i].attr('text'))
print('='.center(90,"="))
name1=poco("android.view.ViewGroup").child()[0].attr('text')
print(name1)
========================
9
UIObjectProxy of "android.view.ViewGroup/[0]"
手机管家
UIObjectProxy of "android.view.ViewGroup/[1]"
None
UIObjectProxy of "android.view.ViewGroup/[2]"
图库
UIObjectProxy of "android.view.ViewGroup/[3]"
钱包
UIObjectProxy of "android.view.ViewGroup/[4]"
应用市场
UIObjectProxy of "android.view.ViewGroup/[5]"
None
UIObjectProxy of "android.view.ViewGroup/[6]"
None
UIObjectProxy of "android.view.ViewGroup/[7]"
None
UIObjectProxy of "android.view.ViewGroup/[8]"
None
==========================================================================================
手机管家

三: Airtest log

python-自动化Airtest-4 log介绍
https://blog.csdn.net/weixin_42914706/article/details/125590504

  • 4
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

45度看我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值