uiautomator2笔记

一、环境安装

pip3 install -U uiautomator2
pip3 install -U weditor
命令行输入:weditor   即可打开UI结构树界面

网址:https://github.com/openatx/uiautomator2

二、命令行 uiautomator2

查看命令帮助:uiautomator2 --help

  • 截图:uiautomator2 screenshot 123.jpg
  • 获取当前的包名和activity:uiautomator2 current

三、API命令

1、设置元素查找等待时间
  • 设置:
    d.implicitly_wait(10.0)
    d.settings[‘wait_timeout’] = 10.0
  • 查看: print(“wait timeout”, d.implicitly_wait())
2、启动APP
  • 如果启动失败:可以考虑加上use_monkey=True
3、 文件上传下载
  • 推送文件

    # 推送到文件夹
    d.push("foo.txt", "/sdcard/")
    
    # 推送并重名
    d.push("foo.txt", "/sdcard/bar.txt")
    
    # 推送文件对象
    with open("foo.txt", 'rb') as f:
        d.push(f, "/sdcard/")
    
    # 推送文件,并且修改权限
    d.push("foo.sh", "/data/local/tmp/", mode=0o755)
    
4、打开web浏览器
d.open_url("https://www.baidu.com")
5、手机终端运行Linux命令
  • 简单使用

    # 默认超时60s
    output, exit_code = d.shell("pwd", timeout=60) 
    
    output = d.shell("pwd").output
    exit_code = d.shell("pwd").exit_code
    
    output, exit_code = d.shell(["ls", "-l"])
    
  • 长时间运行

    r = d.shell("logcat", stream=True)
    
    deadline = time.time() + 10 # 打印10s
    try:
        for line in r.iter_lines(): # r.iter_lines(chunk_size=512, decode_unicode=None, delimiter=None)
            if time.time() > deadline:
                break
            print("Read:", line.decode('utf-8'))
    finally:
        r.close()
    
6、会话
sess = d.session("com.netease.cloudmusic") # start 网易云音乐
sess.close() # 停止网易云音乐
sess.restart() # 冷启动网易云音乐
sess(text="Music").click() 
7、按键事件
  • 关闭开启屏幕

    d.screen_on()
    d.screen_off()
    d.info.get('screenOn')
    
  • 按键

    d.press("home")
    d.press("back")
    
  • 解锁屏幕

    d.unlock()
    
  • 鼠标事件

    d.click(x, y)
    d.double_click(x, y, 0.1)
    d.long_click(x, y, 0.5)
    
    d.swipe(sx, sy, ex, ey, 0.5)  # sx,sy 滑动到 ex,ey
    d.swipe_ext("right") # 手指右滑,4选1 "left", "right", "up", "down"
    d.swipe_ext("right", scale=0.9) # 默认0.9, 滑动距离为屏幕宽度的90%
    d.swipe_ext("right", box=(0, 0, 100, 100)) # 在 (0,0) -> (100, 100) 这个区域做滑动
    d.swipe_points([(x0, y0), (x1, y1), (x2, y2)], 0.2))  # 解锁九宫格
    
    # 拖动
    d.drag(sx, sy, ex, ey)
    d.drag(sx, sy, ex, ey, 0.5) # swipe for 0.5s(default)
    
    以上均支持百分比操作:如d.long_click(0.5, 0.5)  代表点击中间位置
    
  • 输入

    d.set_fastinput_ime(True) # 切换成FastInputIME输入法
    d.send_keys("你好123abcEFG") # adb广播输入
    d.clear_text() # 清除输入框所有内容
    d.set_fastinput_ime(False) # 切换成正常的输入法
    
8、简单选择器(自带方式)
  • 文本(text)

    d(text="显示").click()   # 精确匹配
    d(textContains="显示").get_text()  # 包含
    d(textMatches="^显示$")  # 正则 以显为开头,示为结束
    d(textStartsWith="显示") # 以什么开头
    
  • 类名( className android.widget.LinearLayout)

    d(className="android.widget.TextView",instance=0).get_text()  # 使用第一个符合类的属性
    d(classNameMatches=".+TextView$",instance=0).get_text()  # 正则匹配
    
  • 描述(description )

    description, descriptionContains, descriptionMatches, descriptionStartsWith
    
  • ID( resourceId )

    resourceId, resourceIdMatches
    
  • 多个相同的元素

    使用属性:instance指定哪一个
    
    d(textContains="显示",instance=0).get_text()  # 指定第一个
    
    d(textContains="显示")[0]  # 指定第一个
    
    for i in d(textContains="显示"):
        print(i.text)
    
9、关系选择器
  • 后代选择

    d(className="android.widget.LinearLayout").child(text="网络和互联网").click()
    d(className="android.widget.LinearLayout").child(resourceId="android:id/widget_frame").child(resourceId="com.android.settings:id/switchWidget").click()
    
  • 兄弟选择

    # 所有的兄弟姐妹,包含自己
    d(text="网络和互联网").sibling(className="android.widget.TextView") 
    
10、元素
  • 元素判断

    d(text="Settings").exists
    d(text="Settings").exists(timeout=3)
    d(text="WLAN").wait(timeout=3)
    # 存在则返回 True  
    # 不存在返回 False
    
  • 文本操作

    d(text="Settings").get_text()  # get widget text
    d(text="Settings").set_text("My text...")  # set the text
    d(text="Settings").clear_text()  # clear the text
    
  • 点击

    d(text="Settings").click()
    d(text="Settings").click(timeout=10)
    d(text='Settings').click_exists(timeout=10.0)
    d(text="Settings").click_gone(maxretry=10, interval=1.0)  # 每隔1s 最多点击10次,等待元素不见返回bool
    d(text="Settings").long_click(duration=2)   # 长点击多长时间释放
    
  • 等待元素消失

    d(text="Settings").wait(timeout=3.0) # return bool  等待3S出现
    d(text="Settings").wait_gone(timeout=1.0)  # 等待1S消失
    
11、监控
  • 注册监控

    # 常用写法,注册匿名监控
    d.watcher.when("安装").click()
    
    # 注册名为ANR的监控,当出现ANR和Force Close时,点击Force Close
    d.watcher("ANR").when(xpath="ANR").when("Force Close").click()
    
    # 其他回调例子
    d.watcher.when("抢红包").press("back")
    d.watcher.when("//*[@text = 'Out of memory']").call(lambda d: d.shell('am force-stop com.im.qq'))
    
    # 回调说明
    def click_callback(d: u2.Device):
        d.xpath("确定").click() # 在回调中调用不会再次触发watcher
    
    d.xpath("继续").click() # 使用d.xpath检查元素的时候,会触发watcher(目前最多触发5次)
    
  • 监控操作

    # 移除ANR的监控
    d.watcher.remove("ANR")
    
    # 移除所有的监控
    d.watcher.remove()
    
    # 开始后台监控
    d.watcher.start()
    d.watcher.start(2.0) # 默认监控间隔2.0s
    
    # 强制运行所有监控
    d.watcher.run()
    
    # 停止监控
    d.watcher.stop()
    
    # 停止并移除所有的监控,常用于初始化
    d.watcher.reset()
    
12、XPath选择器

https://github.com/openatx/uiautomator2/blob/master/XPATH.md

注意事项: 有些属性的名字有修改需要注意

description -> content-desc
resourceId -> resource-id
  • 常见用法

    d.xpath("//android.widget.TextView").wait(10.0)
    
    d.xpath("//*[@content-desc='分享']").click()
    
    if d.xpath("//android.widget.TextView[contains(@text, 'Se')]").exists:
        print("exists")
    
    for elem in d.xpath("//android.widget.TextView").all():
        print("Text:", elem.text)
    
  • 多个条件点位(and)

    d.xpath('//android.widget.Button').xpath('//*[@text="私人FM"]')
    
  • 定位到父元素

    d.xpath('@personal-fm') # 等价于 d.xpath('//*[@resource-id="personal-fm"]')
    
    d.xpath('//*[@text="私人FM"]').parent() # 定位到父元素
    d.xpath('//*[@text="私人FM"]').parent("@android:list") # 定位到符合条件的父元素
    
  • 后代元素

    d.xpath('@android:id/list').child('/android.widget.TextView').click()
    # 等价于下面这个
    d.xpath('//*[@resource-id="android:id/list"]/android.widget.TextView').click()
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值