UIautomator2:APP自动化测试方法与小技巧记录(文末附实用APP测试脚本编写模板)
uiautomator2
是一个python的用来自动化操作手机的库,可用于APP自动化测试。就笔者的使用体验,比appuim
更稳定、易用。本文以大家最常用的APP:微信为例子,记录uiautomator2
的常见用法,便于自己和读者查阅。如果你觉得本文有用,还请收藏支持一下。
为方便查阅,环境配置及安装放在最后。
有问题也欢迎联系我:hausahan@gmail.com,问题解决后我会将问题添加在常见问题中。
- 文末附实用APP测试脚本编写模板
目录
- 常见用法及技巧
- 连接设备
- 打开APP
- 使用包名打开
- 回到主屏幕使用text打开
- 元素定位
- text
- id
- xpath
- 坐标
- 常见操作
- 触摸/点击
- 双击
- 长按
- 滑动
- 输入
- 获取文字
- 拖拽元素
- 等待ui对象的出现/消失
- 小技巧
- 当点击元素后页面切换且等待加载的时间不确定时
- 常见问题及报错
- 安装时报错
- `Read timed out`
- 环境安装
常见用法及技巧
连接设备
在终端输入:adb devices
,可以获取连接了电脑的手机名称。
另外,使用
adb shell dumpsys window | grep mCurrentFocus # Linux
adb shell dumpsys window | findstr mCurrentFocus # Windows
可以获取当前屏幕显示的APP的包名。
使用如下代码连接到手机:
class Phone:def __init__(self, deviceName, appName):self.deviceName = deviceNameself.appName = appNameself.d = u2.connect_usb(deviceName)
打开APP
使用包名打开
例如我们要打开微信,可以使用上面的命令获取微信的包名,是:com.tencent.mm
,然后在代码中打开:
class Phone:def __init__(self, deviceName, appName):self.deviceName = deviceNameself.appName = appNameself.d = u2.connect_usb(deviceName) # connect to mobileself.d.app_start(appName) # open the app which the package name is [appName]if __name__ == '__main__':# ConfigdeviceID = '9a9abd39' # mobil device name: adb devicesappID = 'com.tencent.mm' # app package name: adb shell dumpsys window | grep/findstr mCurrentFocusphone = Phone(deviceID, appID)
回到主屏幕使用text打开
如图,我们可以使用定位text的功能,在安卓主屏幕打开app:
到我们的代码中就是将原来的self.d.app_start(appName)
改为self.d(text='工作专用').click()
介绍第两种方法是因为,有时候会出现使用包名不能打开APP的情况,比如APP有分身,那么两个app的包名就会是一样的,打开很不方便。或者偶尔会uiautomator2抽风打不开之类的情况,使用text打开一般会更方便。
元素定位
text
text定位是最简单最常用的,使用方法如下:
屏幕如下时,想要点击的元素又是实时生成没有固定的ID,就可以使用这样的代码来点击:
# coding:utf-8import uiautomator2 as u2class Phone:def __init__(self, deviceName, appName):self.deviceName = deviceNameself.appName = appNameself.d = u2.connect_usb(deviceName) # connect to mobileself.d(text='工作专用').click() # 点击打开微信分身def doTest(self):self.d(text='月亮').click() # 点击想要打开的聊天框if __name__ == '__main__':# ConfigdeviceID = '9a9abd39' # mobil device name: adb devicesappID = 'com.tencent.mm' # app package name: adb shell dumpsys window | grep/findstr mCurrentFocusphone = Phone(deviceID, appID)phone.doTest()
当屏幕中有多个关键词时,使用直接使用.click()
可能达不到我们想要的效果,可以对d(text='xxx')
的结果使用索引,如下,修改doTest方法:
def doTest(self):targetPerson = self.d(text='月亮')targetPerson[-1].click()
此外,在测试使用这个脚本的时候可能会发现,打开一些应用时,有时候会有一些加载时间,包括有时候在应用内跳转也会有。如果没有加载好就执行了点击,会因为找不到元素而报错。在本文的小技巧
一章中提供了一种解决方法,可以使用尽可能少的等待时间,保证测试脚本的可用性和稳定性。
id
使用xpath可以定位元素ID比较确定的情况,例如系统底部的返回键/HOME键,或者当屏幕中只有一个输入框等情况,使用方法如下:
self.d(resourceId="com.tencent.mm:id/b8k").click()
有些元素的id很不明显甚至没有,比如微信的输入框,那么就可以用下面的坐标点击方法选中,然后再往里面写入数据。
xpath
在weditor中点击,xpath会出现在中间的表格中
self.d.xpath('//*[@resource-id="com.tencent.mm:id/b79"]/android.widget.RelativeLayout[3]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]').click()
坐标
坐标定位可用于text不确定,元素的xpath随测试变化等各种不确定情况,或者前两者都定位不到元素的情况,使用方法如下:
(P.S. 在屏幕中位置不确定的话,可以先将待点击元素通过滑动到顶部/底部的方法固定到一个位置)
self.d.click(0.5,0.91)
常见操作
触摸/点击
self.d.click()
# or
self.d(text='xxx').click()
# or
self.d.click(float, float)
双击
self.d(xxx).double_click()
长按
self.d(text='工作专用').long_click(duration=1)
滑动
def getSize(self):x = self.d.window_size()[0]y = self.d.window_size()[1]return x, ydef swipeUp(self, t=0.05):l = self.getSize()x1 = int(l[0] * 0.5) # x坐标y1 = int(l[1] * 0.75) # 起始y坐标y2 = int(l[1] * 0.25) # 终点y坐标self.d.swipe(x1, y1, x1, y2, t)
输入
self.d.set_text('text')
self.d.send_keys('text')
获取文字
self.d('定位操作').get_text()
拖拽元素
self.d('定位操作').drag_to(x, y, duration=0.5) # 拖到某个坐标
d(text='定位操作').drag_to(text='定位操作2', duration=0.25) # 拖到某个元素中心位置
等待ui对象的出现/消失
d(text="Settings").wait(timeout=3)
d(text="Settings").wait_gone(timeout=1)
小技巧
当点击元素后页面切换且等待加载的时间不确定时
可以使用如下方法,等待直到需要的页面加载完成。
def wait(self, s):times = 0maxWaitTime = 10while not self.d(text=s).exists:time.sleep(1)times += 1if times > maxWaitTime:log('There might be something wrong, restarting now......')self.doTest()time.sleep(1)
该方法功能是:等待。直到屏幕中出现了某关键词,然后等待1S后继续测试。当等待时间超过
maxWaitTime
时,就log错误信息,然后重新执行测试方法。相关方法在文末的脚本中有。
例如,初次打开微信会有那个地球的加载页,就可以使用这一方法等待其加载完成:
class Phone:def __init__(self, deviceName, appName):self.deviceName = deviceNameself.appName = appNameself.d = u2.connect_usb(deviceName) # connect to mobileself.d(text='工作专用').click()def doTest(self):self.wait('微信')targetPerson = self.d(text='月亮')targetPerson[-1].click()def wait(self, s):times = 0maxWaitTime = 10while not self.d(text=s).exists:time.sleep(1)times += 1if times > maxWaitTime:log('There might be something wrong, restarting now......')self.doTest()time.sleep(1)if __name__ == '__main__':# ConfigdeviceID = '9a9abd39' # mobil device name: adb devicesappID = 'com.tencent.mm' # app package name: adb shell dumpsys window | grep/findstr mCurrentFocusphone = Phone(deviceID, appID)phone.doTest()
为什么不使用uiaotumator提供的wait方法?因为笔者觉得自己的用着更顺手一些,方便自定义重新开始的位置等。
常见问题及报错
安装时报错
Read timed out
此错误是连接时长超时,可以尝试加长超时时间,在使用pip时加上如下参数:pip --default-timeout=1000 install -U --pre uiautomator2
环境安装
安装过程常见问题和报错请参考:常见问题及报错—>安装时报错
电脑中需要有:Python、Android SDK,若没有,请点击链接前往安装。(SDK的链接是Android Studio的,因为笔者觉得通过这一方式获取的SDK是最官方的,而且这里也可以安装最方便官方的模拟器)
另外Linux系统需要配置环境变量才能使adb可以工作,请参考常见问题。
环境准备好后,在终端/命令行操作:
pip3 install uiautomator2
pip3 install weditor==0.6.4
然后使用数据线连接手机,打开USB调试,或直接使用Android Studio的模拟器,在终端输入:
weditor
或者python3 -m weditor
初次运行会在手机上安装ATX调试器。请及时在手机上允许安装。
输入上面的命令后,会弹出默认浏览器打开调试网页,点击页面中间的Dump Hierachy
可以获取最新手机屏幕页面。
双击手机页面截图可以在右侧生成代码并执行操作。
这一调试器很好用,稍微摸索一下就可以满足一般使用,不再赘述。
在模拟器中安装微信:在官网下载对应位的APK安装包,然后在模拟器打开,或连接了手机的情况下,在终端使用:
adb install weixinxxxxxx.apk
将其安装到模拟器/手机上。
# coding:utf-8
import threadingimport uiautomator2 as u2
import time, datetime
from random import randintimport osdef log(s):print('[{}]: {}'.format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), s))class Phone:def __init__(self, deviceName, appName):self.deviceName = deviceNameself.appName = appNameself.d = u2.connect_usb(deviceName) # connect to mobiledef doTest(self):self.d.app_stop_all()self.d.app_start(self.appName)self.wait('微信')def wait(self, s):times = 0maxWaitTime = 10while not self.d(text=s).exists:time.sleep(1)times += 1if times > maxWaitTime:log('There might be something wrong, restarting now......')self.doTest()time.sleep(1)if __name__ == '__main__':# ConfigdeviceID = '9a9abd39' # mobil device name: adb devicesappID = 'com.tencent.mm' # app package name: adb shell dumpsys window | grep/findstr mCurrentFocusphone = Phone(deviceID, appID)phone.doTest()
UIautomator2:APP自动化测试方法与小技巧记录(文末附实用APP测试脚本编写模板)相关推荐
- 80行代码自己动手写一个表格拆分与合并小工具(文末附工具下载)
点击上方"Python爬虫与数据挖掘",进行关注 回复"书籍"即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 瑶池阿母绮窗开,黄竹歌声动地哀. ...
- 30个数据可视化小技巧(文末赠书)
和数据打交道的朋友肯定经常会通过可视化的方式来呈现数据.在这里小编给大家总结了数据可视化制作的30个小技巧,通过列举一些容易被忽略的常见错误,希望最终能够快速提升和巩固你的可视化制作水平(来源:Dat ...
- 【技巧】windows下网络抓包-netsh技巧(文末附免费学习资料)
相信大家做一些项目,在获取到pc权限后,翻翻文件,查查浏览器记录,但是有些浏览器的账户密码,读取不出来,一些基于key验证的应用提取不出来,如果权限比较高或者过uac的情况下,我们也可以抓取用户的流量 ...
- Golang 中使用 JSON 的一些小技巧 陶文 陶文 3 个月前 有的时候上游传过来的字段是string类型的,但是我们却想用变成数字来使用。 本来用一个json:,string 就可以支持了
Golang 中使用 JSON 的一些小技巧 陶文 3 个月前 有的时候上游传过来的字段是string类型的,但是我们却想用变成数字来使用. 本来用一个json:",string" ...
- 微信小程序/uni-app 蓝牙打印开发教程和常见问题总结【文末附源码】
微信小程序/uni-app 蓝牙打印开发教程和常见问题总结[文末附源码] 文章目录 微信小程序/uni-app 蓝牙打印开发教程和常见问题总结[文末附源码] 1️⃣ 写在前面 2️⃣ 蓝牙连接流程 3 ...
- Linux中_Ubuntu上_命令_使用小技巧记录
Linux特殊命令使用小技巧心得记录 查看gpu使用率: 查看系统使用情况: 在终端杀死进程: 查看内存使用情况: 系统跟踪器//或者按alt + F2打开运行窗口,输入: 重启服务器上Mysql服务 ...
- App 推广有哪些小技巧?
App推广小技巧: 1 学会用shareinstall掌握渠道统计数据 通过集成Shareinstall,开发者可根据自身APP的业务参数.软硬件参数.结合自身业务,对APP的流程进行优化重整,以便向 ...
- 有什么适合小团队记录任务清单的协作APP工具?
有什么适合小团队记录任务清单用的协作APP工具? 待办事项.任务清单类办公软件,通常是一些桌面便签.桌面日历等,在这类办公软件中,具备团队协作能力的,云便签敬业签算作一个. 云便签敬业签是一款专为商务 ...
- 使用mspaint改变图片大小的一个小技巧记录
有些时候,我们截取了一系列图片,放置到某个MFC里面,像ImageList: 但由于原始大小的不同,图片被拉长或拉短的变形了,会比较难看. 办法通常有两个: 1. 重新按比例截取图片 2. 把图片进行 ...
最新文章
- 2021数据挖掘赛题方案来了!
- 寒假每日一题2022【week1 完结】
- OpenCV 高级API:TextDetectionModel和TextRecognitionModel
- 乱用信用卡?黑名单见
- linux怎么添加更新源,在Deepin 15.7系统中不需要在/etc/apt/sources.list添加更新源
- Dream------Hadoop--HDFS的设计
- [SHELL]监控LINUX目录文件变化
- 【连载】如何掌握openGauss数据库核心技术?秘诀三:拿捏存储技术(7)
- [BZOJ2331]地板(插头DP)
- 【Gym - 101234J】Zero Game【单调队列】
- 【FreeRTOS的SOEM-master(1.4.1)移植】
- c语言 zipf分布,Zipf分布:如何测量Zipf分布
- 大学计算机应用教程马秀麟,大学计算机基础电子教案.docx
- Zephyr RTOS -- FIFO (LIFO)
- 如何根据视频的宽屏与竖屏来排序?
- 《7天精通直播带货》运营型主播成长型,提升直播能力与技巧
- 华为服务器如何开机自动启动不了,华为手机开不了机怎么办 开机后一直停留在开机画面的解决方法(3)...
- python安装第三方包_python 怎么安装第三方包
- 楼宇系统服务器,【产品介绍】楼宇管理平台
- php 二维码白边,php生成缩略图自动填充白边例子
热门文章
- JS 案例 树形菜单
- [渝粤教育] 西南科技大学 英语(A)1 在线考试复习资料
- RDD优化--RDD共享变量(广播变量与累加器)
- Edge检查更新时出错:无法连接到Internet。如果使用防火墙,请将 MicrosoftEdgeUpdate.exe 加入允许列表中。
- 51单片机二进制转bcd码c语言,二进制数转换为BCD码(义隆单片机)
- 问题事件名称: APPCRASH(解决方法)
- Gerrit报错:Permission denied publickey的解决办法
- linux java模拟器_在Android模拟器和Ubuntu上测试Linux驱动
- 02 | 该如何选择消息队列?
- 【TP5】安装Guzzle并简单使用