『App自动化测试之Appium应用篇』| uiautomator + accessibility_id定位方法完全使用攻略
2023-12-16 11:33:32
    		『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.jar和uiautomatorviewer.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上传到手机:
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文件,保存到手机中:
adb shell uiautomator dump /sdcard/an.uix
- 将手机中的uix文件下载到本地:
adb pull /sdcard/an.uix
- 使用以下命令截取png文件,保存到手机中:
adb shell screencap -p /sdcard/an.png
- 将手机中的png文件下载到本地:
adb pull /sdcard/an.png

- 打开uiautomatorviewer后,导入这两个本地文件即可:
  
2 accessibility_id定位说明
- accessibility_id定位主要使用的是元素的- content-desc内容;
- 元素的content-desc主要是针对的是Android;
- 而iOS上用的是label或name属性;
- 比如安卓上的如下:
  
3 accessibility_id定位方式
- accessibility_id定位方式方式直接使用的方法是:
AppiumBy.ACCESSIBILITY_ID
- 源码中是这么写的:
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'
- 示例比如:
driver.find_element(AppiumBy.ACCESSIBILITY_ID, "Browser").click()
4 bounds坐标定位说明
- 关于坐标定位,能不用就不用,为啥呢?
- 我们之前提供了很多的定位方式,但是有时候需要用坐标才能定位到;
- 但是使用坐标定位很不稳定,它和手机的分辨率、屏幕尺寸等有关系;
- 这样同一套代码可能在不同的机器上运行不下去,需要投入大量的人力进行代码修改优化,很是麻烦;
- 坐标定位使用的是元素的bounds属性;
- 在uiautomatorviewer的最后一行:
  
- 这个坐标有两对,分别代表是按钮左上角的坐标和按钮右下角的坐标。
5 bounds坐标定位方式
- bounds坐标定位方式为:
driver.tap()
- 这个tap()使用如下:
    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
        """
- 所以示例为:
driver.tap([(605,1022), (739,1178)], duration=50)
6 uiautomator定位简介
- uiautomator是- Android原生的定位方式;
- 相对于以前提及的定位方式它的优势是功能比较强大,速度快;
- 定位样式和xpath差不多,支持元素的全部属性定位;
- 定位方法为:
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定位:
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整个内容,而不是属性名;
id_ele = 'resourceId("com.taobao.taobao:id/provision_positive_button")'
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, id_ele).click()
8.3 其他方法
- 关于其他方式也是类似的,比如className、组合定位、父子定位等。
    			文章来源:https://blog.csdn.net/NoamaNelson/article/details/134998857
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
    	本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!