『App自动化测试之Appium应用篇』| uiautomator + accessibility_id定位方法完全使用攻略

1 uiautomatorviewer无法连接手机

1.1 问题现象

  • 当使用自带的uiautomatorviewer.bat连接真机时,提示以下报错:
  • 原因是我连接的是真机,而操作系统是Android13,但是自带的uiautomatorviewer不支持Android8.0之后的操作系统了。

1.2 解决方法

1.2.1 方法一:使用第三方文件(不建议)

  • 使用二次开发好的uiautomatorviewer,本文试过了安卓9.0可以,但是安卓13是不行的;
  • 这个可以直接搜索,比如如下这个:
  • 下载后有三个文件,uiautomatorviewer.jaruiautomatorviewer.jar2属于同一个文件只是页面功能略有不同,一次只可使用一个,不管下载那个最后必须重命名为uiautomatorviewer.jar
  • 进入SDK目录的D:\android-sdk-windows\tools\lib目录下,找到老的uiautomatorviewer.jar重新命名uiautomatorviewer.zip或者移动到其他地方去;
  • 将下载好的uiautomatorviewer.jar 、uiautomatorviewer.jar2复制到D:\android-sdk-windows\tools\lib目录下:
  • 将下载好的LvmamaXmlKit.jar上传到手机:
python 复制代码
F:\monkey_test>adb push LvmamaXmlKit.jar /sdcard/
LvmamaXmlKit.jar: 1 file pushed, 0 skipped. 0.0 MB/s (1118 bytes in 0.027s)
  • 重新尝试可以连接了(安卓9可以,安卓13不行):

1.2.2 方法二:导入uix和png文件

  • 使用以下命令截取uix文件,保存到手机中:
python 复制代码
adb shell uiautomator dump /sdcard/an.uix
  • 将手机中的uix文件下载到本地:
python 复制代码
adb pull /sdcard/an.uix
  • 使用以下命令截取png文件,保存到手机中:
python 复制代码
adb shell screencap -p /sdcard/an.png
  • 将手机中的png文件下载到本地:
python 复制代码
adb pull /sdcard/an.png
  • 打开uiautomatorviewer后,导入这两个本地文件即可:

2 accessibility_id定位说明

  • accessibility_id定位主要使用的是元素的content-desc内容;
  • 元素的content-desc主要是针对的是Android
  • iOS上用的是labelname属性;
  • 比如安卓上的如下:

3 accessibility_id定位方式

  • accessibility_id定位方式方式直接使用的方法是:
python 复制代码
AppiumBy.ACCESSIBILITY_ID
  • 源码中是这么写的:
python 复制代码
class AppiumBy(By):
    IOS_PREDICATE = '-ios predicate string'
    IOS_UIAUTOMATION = '-ios uiautomation'
    IOS_CLASS_CHAIN = '-ios class chain'
    ANDROID_UIAUTOMATOR = '-android uiautomator'
    ANDROID_VIEWTAG = '-android viewtag'
    ANDROID_DATA_MATCHER = '-android datamatcher'
    ANDROID_VIEW_MATCHER = '-android viewmatcher'
    # Deprecated
    WINDOWS_UI_AUTOMATION = '-windows uiautomation'
    ACCESSIBILITY_ID = 'accessibility id' # 用的是这个
    IMAGE = '-image'
    CUSTOM = '-custom'
  • 示例比如:
python 复制代码
driver.find_element(AppiumBy.ACCESSIBILITY_ID, "Browser").click()

4 bounds坐标定位说明

  • 关于坐标定位,能不用就不用,为啥呢?
  • 我们之前提供了很多的定位方式,但是有时候需要用坐标才能定位到;
  • 但是使用坐标定位很不稳定,它和手机的分辨率、屏幕尺寸等有关系;
  • 这样同一套代码可能在不同的机器上运行不下去,需要投入大量的人力进行代码修改优化,很是麻烦;
  • 坐标定位使用的是元素的bounds属性;
  • uiautomatorviewer的最后一行:
  • 这个坐标有两对,分别代表是按钮左上角的坐标和按钮右下角的坐标。

5 bounds坐标定位方式

  • bounds坐标定位方式为:
python 复制代码
driver.tap()
  • 这个tap()使用如下:
python 复制代码
    def tap(self, positions: List[Tuple[int, int]], duration: Optional[int] = None) -> 'WebDriver':
        """Taps on an particular place with up to five fingers, holding for a
        certain time

        Args:
            positions: an array of tuples representing the x/y coordinates of
                the fingers to tap. Length can be up to five.
            duration: length of time to tap, in ms

        Usage:
            driver.tap([(100, 20), (100, 60), (100, 100)], 500)

        Returns:
            Union['WebDriver', 'ActionHelpers']: Self instance
        """
  • 所以示例为:
python 复制代码
driver.tap([(605,1022), (739,1178)], duration=50)

6 uiautomator定位简介

  • uiautomatorAndroid原生的定位方式;
  • 相对于以前提及的定位方式它的优势是功能比较强大,速度快;
  • 定位样式和xpath差不多,支持元素的全部属性定位;
  • 定位方法为:
python 复制代码
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, "xxx")
  • 而传入的参数为一个java对象,对象是UiSelector对象。

7 UiSelector对象API

  • UiSelector对象可以参考:UiSelector
  • 关于UiSelector对象API有以下内容:
API 说明
checked(boolean val) 设置搜索条件以匹配当前选中的小部件(通常用于复选框)
childSelector(UiSelector selector) 将子UiSelector条件添加到此选择器。
className(String className) 设置搜索条件以匹配小部件的类属性(例如,"android.widget.Button"
className(Class<T> type) 设置搜索条件以匹配小部件的类属性(例如,"android.widget.Button")
classNameMatches(String regex) 设置搜索条件以匹配小部件的类属性(例如,"android.widget.Button")
clickable(boolean val) 设置搜索条件以匹配可单击的小部件
description(String desc) 设置搜索条件以匹配小部件的内容描述属性
descriptionContains(String desc) 设置搜索条件以匹配小部件的内容描述属性
descriptionMatches(String regex) 设置搜索条件以匹配小部件的内容描述属性
descriptionStartsWith(String desc) 设置搜索条件以匹配小部件的内容描述属性
enabled(boolean val) 设置搜索条件以匹配已启用的小部件
focusable(boolean val) 设置搜索条件以匹配可聚焦的小部件
focused(boolean val) 设置搜索条件以匹配具有焦点的小部件
fromParent(UiSelector selector) 将子UiSelector条件添加到此选择器,用于从父小部件开始搜索
index(int index) 设置搜索条件,以通过布局层次结构中的节点索引匹配小部件
instance(int instance) 设置搜索条件以按小部件的实例号匹配小部件
longClickable(boolean val) 设置搜索条件以匹配可长时间单击的小部件
packageName(String name) 设置搜索条件以匹配包含小部件的应用程序的包名称
packageNameMatches(String regex) 设置搜索条件以匹配包含小部件的应用程序的包名称
scrollable(boolean val) 设置搜索条件以匹配可滚动的小部件
selected(boolean val) 设置搜索条件以匹配当前选择的小部件
text(String text) 设置搜索条件以匹配小部件显示的可见文本(例如,启动应用程序的文本标签)
textContains(String text) 设置搜索条件以匹配小部件显示的可见文本(例如,启动应用程序的文本标签)
textMatches(String regex) 设置搜索条件以匹配小部件显示的可见文本(例如,启动应用程序的文本标签)
textStartsWith(String text) Text属性通常是小部件在显示器上的可见文本

8 uiautomator定位示例

8.1 text方法

  • text有四种,详见上边提到的API
  • 比如我们对某个元素属性文本是新增,我们使用text定位:
python 复制代码
add_text = 'new UiSelector().text("新增")'
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, add_text).click()

add_text01 = 'new UiSelector().textContains("新")'
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, add_text01).click()

8.2 resourceID方法

  • 直接将resourceID整个内容,而不是属性名;
python 复制代码
id_ele = 'resourceId("com.taobao.taobao:id/provision_positive_button")'
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, id_ele).click()

8.3 其他方法

  • 关于其他方式也是类似的,比如className、组合定位、父子定位等。
相关推荐
rgeshfgreh6 分钟前
Python条件与循环实战指南
python
rgeshfgreh10 分钟前
通达信LC1文件结构解析指南
python
七夜zippoe24 分钟前
事件驱动架构:构建高并发松耦合系统的Python实战
开发语言·python·架构·eda·事件驱动
Kratzdisteln38 分钟前
【MVCD】PPT提纲汇总
经验分享·python
一个无名的炼丹师1 小时前
GraphRAG深度解析:从原理到实战,重塑RAG检索增强生成的未来
人工智能·python·rag
用户8356290780512 小时前
用Python轻松管理Word页脚:批量处理与多节文档技巧
后端·python
进击的松鼠2 小时前
LangChain 实战 | 快速搭建 Python 开发环境
python·langchain·llm
小北方城市网2 小时前
第1课:架构设计核心认知|从0建立架构思维(架构系列入门课)
大数据·网络·数据结构·python·架构·数据库架构
我的offer在哪里2 小时前
Hugging Face:让大模型触手可及的魔法工厂
人工智能·python·语言模型·开源·ai编程
汤姆yu3 小时前
基于python大数据的协同过滤音乐推荐系统
大数据·开发语言·python