Uiautomator2实现Android自动化测试详解

news2024/12/27 10:44:49

目录

1、UIautomator2框架原理

2、UIautomator2使用

2.1、安装

2.2、元素定位工具-weditor

2.3、设备连接

2.4、全局配置

2.4.1、通过settings设置

2.4.2、通过属性设置

2.5、APP相关操作

2.5.1、安装应用

2.5.2、启动应用

2.5.3、等待应用启动

2.5.4、结束应用

2.5.5、卸载应用

2.5.6、获取当前上层APP的信息

2.5.7、获取指定APP的信息

2.6、设备相关操作

2.6.1、获取设备信息

2.6.2、 获取屏幕分辨率

2.6.3、获取设备IP地址

2.6.4、锁屏亮屏

2.6.5、截屏

2.6.6、按键

2.6.7、输入法切换

2.6.8、录屏

2.6.9、文件的上传下载

2.8、元素定位

2.8.1、定位方法

2.8.2、支持的定位方法

2.8.3、 组合定位

2.8.4、子元素定位

2.8.5、兄弟元素定位

2.8.6、多级定位

2.8.9、相对定位

2.8.10、xpath定位

2.9、元素操作

2.9.1、点击

2.9.2、长按

2.9.3、滑动

2.9.4、多点滑动

2.9.5、拖动

2.9.6、放大缩小

2.9.7、滚动

2.9.8、toast操作

2.9.9、文本相关操作

2.9.10、弹窗监测

1、UIautomator2框架原理

如上图所示,python-uiautomator2 主要分为两个部分,python 客户端,移动设备

  • python 端: 执行脚本,脚本通过封装成HTTP 请求发送到移动设备
  • 移动设备:通过 atx-agent 来接受 HTTP 请求,并将这些请求转换为 uiautomator2可识别的指令来实现自动化操作。atx-agent 充当了一个桥梁的角色。

完整流程

  1. 在移动设备上安装atx-agent(守护进程), 通过atx-agent启动 uiautomator2 服务 (默认 7912 端口) 进行监听
  2. 在 PC 上编写测试脚本并执行(相当于发送 HTTP 请求到移动设备的 server 端)
  3. 移动设备通过 WIFI 或 USB 接收到 PC 上发来的 HTTP 请求,执行指定的操作

2、UIautomator2使用

2.1、安装

pip3 install -U uiautomator2

  • 初始化环境,安装包含httprpc服务的apk到手机+atx-agent, minicap, minitouch,注:1.3.0之后的版本,执行python代码u2.connect()时会自动监测和推送这些文件。

python3 -m uiautomator2 init

  • 检查是否安装成功
    • cmd

uiautomator2 verison

  • Python

import uiautomator2 as u2

d = u2.connect() # 连接设备
print(d.info)

2.2、元素定位工具-weditor

1、安装:

  • 注意:这里指定安装0.6.4版本的,如果默认安装最新的,很可能会出现安装失败的问题,这里推荐指定安装。

pip install weditor==0.6.4

2、启动weditor

python -m weditor

3、连接Android设备

2.3、设备连接

1、默认一个设备的情况

import uiautomator2 as u2
# 连接设备
d = u2.connect() 

# 当PC与设备在同一网段时,可以使用IP地址和端口号通过WIFI连接,无需连接USB线
# 默认使用端口号7912
u2.connect("10.0.0.1:7912")
u2.connect("10.0.0.1")
u2.connect("http://10.0.0.1")
u2.connect("http://10.0.0.1:7912")
等价于
u2.connect_wifi("10.0.0.1:7912")

2、多个设备时指定设备连接

import uiautomator2 as u2
# 连接设备,xxx:表示指定设备的设备号,可使用命令adb devices查看
d = u2.connect("xxx") 
等价于
d = u2.connect_usb("xxx")

2.4、全局配置

2.4.1、通过settings设置

1、查看settings默认设置

print(d.settings)

# 默认配置如下:
{
# 截屏失败时返回空白截屏(不抛出异常)
'fallback_to_blank_screenshot': False,
# 操作延迟,(0, 0)表示元素点击前等待0秒,点击后等待0S再执行后续操作
'operation_delay': (0, 0),
# opretion_delay生效的方法,默认为click和swipe
# 还可以设置press,send_keys,long_click等方式
'operation_delay_methods': ['click', 'swipe'],
# 元素默认等待时间(隐式等待)
'wait_timeout': 20.0,
# xpath日志
'xpath_debug': False
 }

2、通过settIng修改默认配置

# 修改截图失败后的默认返回
d.settings["fallback_to_blank_screenshot"] = True
# 修改操作延迟时间
d.settings["operation_delay"] = (3, 3)
# 修改操作延迟方法
d.settings["operation_delay_methods"] = ['click', 'swipe', 'press']
# 修改默认等待时间
d.settings["wait_timeout"] = 10

# 查看是否修改成功
print(d.settings)

2.4.2、通过属性设置

1、http默认请求超时时间

# 默认值60s
d.HTTP_TIMEOUT = 60 

2、等待设备在线时长

# 默认20s
d.WAIT_FOR_DEVICE_TIMEOUT = 60

3、HTTP debug信息

d.debug = True

2.5、APP相关操作

2.5.1、安装应用

# 本地路径安装
d.app_install('tmp.apk')
# url安装
d.app_install('package_url')

2.5.2、启动应用

# 如果已启动且在后台会被拉起到前台
# 如果已启动且在前台,不做任何操作,结束
# 如果未启动,则冷启动该应用
d.app_start("packageName")

# 先kill掉APP,再冷启动APP
d.app_start("packageName", stop=True)

2.5.3、等待应用启动

# 等待此应用变为当前上层应用,返回pid,超时未启动成功则返回0
# front默认为false表示只要该应用在运行中就会返回pid 为true表示等待app成为当前app
d.app_wait('com.xxx', 30, front=True)

2.5.4、结束应用

# 通过包名结束单个应用
d.app_stop("packageName") # 强制结束应用,但是不清除应用数据
d.app_clear('packageName') # 结束应用,并且清除应用数据

# 默认结束所有第三方应用,保留uiautomator两个依赖服务应用
# excludes参数:排除列表中的应用包名
d.app_stop_all(excludes=['com.xxx.xxx'])

2.5.5、卸载应用

# 卸载成功返回true,没有此包或者卸载失败返回False
d.app_uninstall('com.xxx.xxx')

2.5.6、获取当前上层APP的信息

d.app_current()

2.5.7、获取指定APP的信息

d.app_info("com.XXX")

2.6、设备相关操作

2.6.1、获取设备信息

# 输出设备的详细信息,报告设备号,电池,CPU信息等
d.device_info

2.6.2、 获取屏幕分辨率

# 手机竖屏状态返回 (1080,2400)
# 横屏状态返回 (2400,1080)
d.window_size()

2.6.3、获取设备IP地址

d.wlan_ip

2.6.4、锁屏亮屏

# 锁屏
d.screen_off()
# 亮屏
d.screen_on()

2.6.5、截屏

# 截图,save(fp) 传文件路径地址
d.screenshot().save("./tmp.png")

from PIL import Image

# 旋转90度截屏(逆时针旋转)
d.screenshot().transpose(Image.ROTATE_90).save("./tmp2.png")

2.6.6、按键

# 按音量键"+"
d.press('volume_up')

"""
press key via name or key code. Supported key name includes:
    home, back, left, right, up, down, center, menu, search, enter,
    delete(or del), recent(recent apps), volume_up, volume_down,
    volume_mute, camera, power.
"""

2.6.7、输入法切换

# 切换成uiautomator2的输入法,这里会隐藏掉系统原本的输入法,默认是使用系统输入法
# 当传入False时会使用系统默认输入法,默认为Fasle
d.set_fastinput_ime(True)

# 查看当前输入法
d.current_ime()

2.6.8、录屏

  • 需要下载依赖,官方推荐使用镜像下载

pip3 install -U "uiautomator2[image]" -i https://pypi.doubanio.com/simple

# 启动录制,默认帧率为20
d.screenrecord('tmp.mp4')
# 执行其它操作
time.sleep(10)
# 停止录制,录制结束后生成视频
d.screenrecord.stop()

2.6.9、文件的上传下载

# 上传文件(从电脑推送到手机) 如果是目录,这里"/sdcrad/"最后一个斜杠一定要加,否则会报错
d.push("test.txt","/sdcrad/")
d.push("test.txt","/sdcrad/test.txt")

# 下载文件(从手机推送到电脑)
d.pull('/sdcard/test.txt','text.txt')

2.7、等待

说明:等待分为强制等待和隐式等待;

  • 强制等待:不管元素是否加载,都强制等待指定时间,实际根据具体情况进行配置,只在使用的地方生效。
  • 隐式等待:在规定时间内如果元素可操作,直接进行操作;不必强制等到指定的时间;如果超过规定的时间,元素不可进行操作会抛出异常。一般会在全局配置的时候进行统一配置,配置每一步的操作都会生效。
# 设置强制等待的时间为3秒,等价于:time.sleep(3)
d.sleep(3)
 
# 设置隐式等待的时间为10
d.implicitly_wait(10)

2.8、元素定位

2.8.1、定位方法

d(定位方法=定位方法的值)

# 示例
#返回一个列表,当没找到元素时,返回一个空列表;存在多个元素时,返回多个列表元素
elements = d(text='Setting')
elements[0].click()
#获取元素个数
print(elements.count)

2.8.2、支持的定位方法

定位方法

描述

text

text是指定文本的元素

textContains

text中包含有指定文本的元素

textMatches

text符合指定正则的元素

textStartsWith

text以指定文本开头的元素

className

className是指定类名的元素

classNameMatches

className类名符合指定正则的元素

description

description是指定文本的元素

descriptionContains

description中包含有指定文本的元素

descriptionMatches

description符合指定正则的元素

descriptionStartsWith

description以指定文本开头的元素

checkable

可检查的元素,参数为True,False

checked

已选中的元素,通常用于复选框,参数为True,False

clickable

可点击的元素,参数为True,False

longClickable

可长按的元素,参数为True,False

scrollable

可滚动的元素,参数为True,False

enabled

已激活的元素,参数为True,False

focusable

可聚焦的元素,参数为True,False

focused

获得了焦点的元素,参数为True,False

selected

当前选中的元素,参数为True,False

packageName

packageName为指定包名的元素

packageNameMatches

packageName为符合正则的元素

resourceId

resourceId为指定内容的元素

resourceIdMatches

resourceId为符合指定正则的元素

2.8.3、 组合定位

  • 通过不同属性的组合来完成最终元素的定位,注意:该方式定位一定是同一个层级的,如果是不同层级的则会定位失败。
d(className="xxx",  text="xxx")

2.8.4、子元素定位

  • 该方式定义一定是父子层级的关系才能成功定位,不然会定位失败。
d(className="xxx").child(text="xxx")

2.8.5、兄弟元素定位

  • 注意:返回结果包含元素自己本身
d(text="xxx").sibling(className="android.widget.TextView")

2.8.6、多级定位

d(className="xxx", resourceId="xxx").child_by_text("xxx").child(className="xxxx")

2.8.9、相对定位

d(A).left(B),# 选择A左边的B
d(A).right(B),# 选择A右边的B
d(A).up(B), #选择A上边的B
d(A).down(B),# 选择A下边的B
# 示例
d(text='xxx').right(className="android.widget.TextView")

2.8.10、xpath定位

  • 注意事项:
    • Java uiautoamtor默认是不支持xpath,这是属于uiautoamtor2的扩展功能,速度会比其它定位方式慢
    • 在xpath定位中,uiautoamtor2中的description 定位需要替换为content-desc,resourceId 需要替换为resource-id
# 如果找不到元素,则会报XPathElementNotFoundError错误
# 如果找到多个元素,默认返回第1个
d.xpath('//*[@content-desc="xxx"]')

# 如果想要返回的元素有多个,使用all()方法返回列表
# 使用all方法,当未找到元素时,不会报错,会返回一个空列表
d.xpath('//*[@resource-id="xxx"]').all()

2.9、元素操作

2.9.1、点击

d(text='xxx').click()
#单击直到元素消失,超时时间5,点击间隔1
d(text='xxx').click_gone(maxretry=5, interval=1.0)

2.9.2、长按

d(text='xxx').long_click()

2.9.3、滑动

# 根据坐标滑动从(x1,y1)滑动到(x2,y2)
d.swipe(x1,y1,x1,y2)

# 滑动的扩展方法,支持上下左右的滑动
# "left", "right", "up", "down"
d.swipe_ext("up")

2.9.4、多点滑动

  • 可用来实现图案解锁
# 按下不放手
touch.down(x,y)
# 停住1S
touch.sleep(1)
# 移动
touch.move(x,y)
# 放开
touch.up(x,y)
#实现长按,同一个点按下休眠10S后抬起
d.touch.down(x1,y1).sleep(10).up(x1,y1)
# 实现多点之间的移动
d.touch.down(x1,y1).move(x2,y2).move(x3,y3).up(x3,y3)

2.9.5、拖动

# 在0.5s内将设置拖动至QQ上,拖动元素的中心位置
# duration默认为0.5,实际拖动的时间会比设置的要高
d(description="设置").drag_to(text="QQ", duration=0.5)

# 拖动设置到屏幕的(500, 500)位置上
d(text="设置").drag_to(500,500, duration=0.5)

# 从点(x1,y1)拖动到点(x2,y2)
d.drag(x1,y1,x2,y2)

2.9.6、放大缩小

# 根据坐标进行放大和缩小
d(className="android.widget.FrameLayout").gesture(start1,start2,end1,end2)

#  缩小
d(className="android.widget.FrameLayout").pinch_in(50, 50)
# 放大
d(className="android.widget.FrameLayout").pinch_out(10, 10)

2.9.7、滚动

  • 说明:
    • 设置scrollable属性为True
    • 滚动类型:horiz 为水平 vert 为垂直
    • 所有方法均返回Bool值
    • 滚动方向:forward 向前 、backward 向后 、toBeginning 滚动至开始 、toEnd 滚动至最后 、to 滚动直接某个元素出现
# 垂直滚动到页面顶部/横向滚动到最左侧
d(scrollable=True).scroll.toBeginning()
d(scrollable=True).scroll.horiz.toBeginning()
# 垂直滚动到页面最底部/横向滚动到最右侧
d(scrollable=True).scroll.toEnd()
d(scrollable=True).scroll.horiz.toEnd()
# 垂直向后滚动到指定位置/横向向右滚动到指定位置
d(scrollable=True).scroll.to(text="指定位置")
d(scrollable=True).scroll.horiz.to(text="指定位置")
# 垂直向前滚动(横向同理)
d(scrollable=True).scroll.forward()
# 垂直向前滚动到指定位置(横向同理)
d(scrollable=True).scroll.forward.to(text="指定位置")

2.9.8、toast操作

# 获取toast,当没有找到toast消息时,返回default内容
d.toast.get_message(timout=3, default='no toast')
# 清空toast缓存
d.toast.reset()

2.9.9、文本相关操作

# 获取元素文本
d(text="xxx").get_text()

# 设置元素文本
d(text="xxx").set_text()

# 清除元素文本
d(text="xxx").clear_text()

2.9.10、弹窗监测

  • 使用wather进行页面监测,可以用来实现弹框的监测处理
  • 当启动wather时,会新建一个线程进行监控 ,可以添加多个watcher
# 注册监控,当页面内出现有OK时,点击OK
d.watcher.when('OK').click()

# 移除 allow 的监控
d.watcher.remove("allow")

# 移除所有的监控
d.watcher.remove()

# 开始后台监控
d.watcher.start()
d.watcher.start(2.0) # 默认监控间隔2.0s

# 强制运行所有监控
d.watcher.run()

# 停止监控
d.watcher.stop()

# 停止并移除所有的监控,常用于初始化
d.watcher.reset()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1457552.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【机器学习笔记】 15 机器学习项目流程

机器学习的一般步骤 数据清洗 数据清洗是指发现并纠正数据文件中可识别的错误的最后一道程序,包括检查数据一致性,处理无效值和缺失值等。与问卷审核不同,录入后的数据清理一般是由计算机而不是人工完成。 探索性数据分析(EDA 探索性数据…

从gradient_checkpointing_enable中学习

1.背景 最近在使用官网的教程训练chatGLM3,但是出现了“RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn”错误,查阅了官方的文档,目前这个问题还没什么解决方案 但是其中有人回复说:是注释掉503行的model.gradient_checkpointing_e…

手持三防平板丨国产化加固平板丨国产三防平板发展的意义是什么?

随着现代科技的快速发展,平板电脑在我们的生活中扮演着越来越重要的角色。然而,传统的平板电脑只能在普通的环境中使用,而无法在恶劣的环境中使用,例如在高海拔、高温、高湿度、沙漠等环境中,传统平板电脑往往会出现故…

OpenHarmony—UIAbility组件间交互(设备内)

UIAbility是系统调度的最小单元。在设备内的功能模块之间跳转时,会涉及到启动特定的UIAbility,该UIAbility可以是应用内的其他UIAbility,也可以是其他应用的UIAbility(例如启动三方支付UIAbility)。 本章节将从如下场…

电脑数据丢失怎么办?5 种免费数据恢复软件能帮到您

我们存储在计算机中的个人和专业数据如果丢失,可能会给我们带来经济和精神上的困扰。有许多情况会导致此类数据丢失;其中一些包括意外删除、硬盘驱动器故障、软件崩溃、病毒攻击等。 5 种最佳免费数据恢复软件 为防止此类事故,建议定期备份计…

智慧城市驿站:智慧公厕升级版,打造现代化城市生活的便捷配套

随着城市化进程的加速,人们对城市生活质量的要求也越来越高。作为智慧城市建设的一项重要组成部分,多功能城市智慧驿站应运而生。它集合了信息技术、设计美学、结构工艺、系统集成、环保节能等多个亮点,将现代科技与城市生活相融合&#xff0…

RK3568平台 有线以太网接口之MAC芯片与PHY芯片

一.平台网络网络通路 平台有线以太网通路:有线以太网一般插入的是RJ45 座要与 PHY 芯片(RTL8306M)连接在一起,但是中间需要一个网络变压器,网络变压器经过模数转换后到达网卡(RTL8111)转换为帧数据后到达SOC。 二.网络…

【初始RabbitMQ】交换机的实现

交换机概念 RabbitMQ消息传递模型的核心思想就是:生产者生产的消息从不会直接发送到队列。实际上,通常生产者不知道这些消息会传递到那些队列中 相反,生产者只能将消息发送到交换机,交换机的工作内容也很简单,一方面…

Kubernetes基础(二十二)-k8s持久化存储详解

1 volume 1.1 介绍 在容器中的磁盘文件是短暂的,当容器崩溃时,Kubelet会重新启动容器,但容器运行时产生的数据文件都将会丢失,之后容器会以最干净的状态启动。另外,当一个Pod运行多个容器时,各个容器可能…

科技守护大唐遗宝,预防保护传承千年

​ 一、“大唐遗宝——何家村窖藏出土文物展” 陕西历史博物馆的“唐朝遗宝——何家村窖藏出土文物展”算得上是博物馆展览的典范。展览不仅在于展现了数量之多、等级之高、种类之全,更在于对唐朝历史文化的深入揭露。 走入大唐财产展厅,好像穿越千年前…

【Azure 架构师学习笔记】- Azure Databricks (7) --Unity Catalog(UC) 基本概念和组件

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (6) - 配置Unity Catalog 前言 在以前的Databricks中,主要由Workspace和集群、SQL Warehouse组成, 这两年Databricks公…

Bert基础(一)--transformer概览

1、简介 当下最先进的深度学习架构之一,Transformer被广泛应用于自然语言处理领域。它不单替代了以前流行的循环神经网络(recurrent neural network, RNN)和长短期记忆(long short-term memory, LSTM)网络,并且以它为基础衍生出了诸如BERT、GPT-3、T5等…

安全架构设计理论与实践

一、考点分布 安全架构概述(※※)安全模型(※※※)信息安全整体架构设计网络安全体系架构设计区块链技术(※※) 二、安全架构概述 被动攻击:收集信息为主,破坏保密性 主动攻击&#…

深度学习发展的艺术

将人类直觉和相关数学见解结合后,经过大量研究试错后的结晶,产生了一些成功的深度学习模型。 深度学习模型的进展是理论研究与实践经验相结合的产物。科学家和工程师们借鉴了人类大脑神经元工作原理的基本直觉,并将这种生物学灵感转化为数学模…

Mac环境Obsidian的ExcaliDraw添加中文字体

Mac环境Obsidian的ExcaliDraw添加中文字体 ExcaliDraw画图工具直接看图 ExcaliDraw画图工具 顾名思义,这是画图用的,但是系统不支持中文字体,所以需要下载中文字体自己放进去。 直接看图

HCIA-HarmonyOS设备开发认证V2.0-IOT硬件子系统-SPI

目录 一、 SPI 概述二、SPI 模块相关API三、接口调用实例四、SPI HDF驱动开发4.1、开发步骤(待续...) 坚持就有收获 一、 SPI 概述 SPI 是串行外设接口(Serial Peripheral Interface)是一种高速的全双工同步的通信总线。 SPI 是由 Motorola 公司开发&a…

VUE3 中导入Visio 图形

微软的Visio是一个功能强大的图形设计工具,它能够绘制流程图,P&ID,UML 类图等工程设计中常用的图形。它要比其它图形设计软件要简单许多。以后我的博文中将更多地使用VISO 来绘制图形。之前我一直使用的是corelDraw。 Visio 已经在工程设…

新增长100人研讨会:快消零售专场探讨招商加盟数字化转型实战

2024年2月2日下午,一场由纷享销客与杨国福集团联合主办的招商加盟数字化转型研讨会在上海成功举办。本次研讨会汇聚了众多快消零售业界的领军人物,共同探讨行业未来的新增长点。 会议伊始,杨国福集团数字化中心负责人王林林发表了主题演讲&a…

php伪协议之phar

一.phar协议 用于将多个 PHP 文件、类、库、资源(如图像、样式表)等打包成一个单独的文件。这个归档文件可以像其他 PHP 文件一样被包含(include)或执行。PHAR 归档提供了一种方便的方式来分发和安装 PHP 应用程序和库&#xff0c…

【unity实战】使用unity制作一个类似Rust的3D生存建造建筑系统(附项目源码)

配置连接点 材质 连接器控制 using System.Collections; using System.Collections.Generic; using UnityEngine;public class Connector : MonoBehaviour {[Header("连接器位置")]public ConnectorPosition connectorPosition;[Header("连接器所属建筑类型&qu…