• Appium自动化(5)- 高级元素定位方式之 UI Automator API


    # 可定位的控件属性

    App中的属性 等价 Web 中的属性 代码表达式 注意点
    resource-id id driver.find_element_by_id("id")
    driver.findElement(By.id("id"))
    在App中,id可能不是唯一的
    class class/tag driver.find_element_by_class_name("class")
    driver.findElement(By.className("class"))
    xpath:
    //class[id = "id"]
    1、当使用 class_name 去定位时,可以理解成类名
    2、当使用xpath定位时,class就是tag(标签名),并不是类名。
    text name driver.find_element_by_name("name")
    driver.findElement(By.name("name"))
    name是一个属性
    content-desc driver.find_element_by_accessibility_id("desc") content-desc属性是用来描述该元素的作用的

    定位入门

    软件:微博国际版

    import time
    from appium import webdriver
    
    desired_caps = {
      "platformName": "android",
      "deviceName": "bc3ef5d5",
      "appPackage": "com.weico.international",
      "appActivity": ".activity.MainFragmentActivity",
      "noReset": True,
      "newCommandTimeout": 6000
    }
    
    driver = webdriver.Remote("http://localhost:4723/wd/hub", desired_caps)
    test = driver.find_element_by_class_name("android.widget.TextView")
    print(test)
    print("打印1:" + test.text)
    
    test = driver.find_element_by_xpath("/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/androidx.drawerlayout.widget.DrawerLayout/android.view.ViewGroup/android.widget.RelativeLayout/android.widget.TabHost/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout/android.widget.FrameLayout/androidx.recyclerview.widget.RecyclerView/android.widget.LinearLayout[2]/android.widget.RelativeLayout[1]/android.widget.TextView[1]")
    print("打印2:" + test.text)
    
    test = driver.find_element_by_xpath("//*[contains(@text,'冈瓦纳')]")
    print("打印3:" + test.text)
    
    
    >>>
    打印1:查看新微博
    打印2:冈瓦纳
    打印3:冈瓦纳
    

    为什么打印1是,查看新微博?

    因为多个class_name的名字是一样的,find_element_by只返回第一个。如果要全部返回,则改成find_elements_by匹配多个元素,再更具索引去匹配

    driver = webdriver.Remote("http://localhost:4723/wd/hub", desired_caps)
    test = driver.find_elements_by_class_name("android.widget.TextView")
    for i in test:
        print("打印1:" + i.text)
        
    >>>
    打印1:查看新微博
    打印1:全部
    打印1:
    打印1:烫师傅
    打印1:11 分钟前
    打印1:iQOO 3 5G性能旗舰
    ...
    

    高级元素定位方式之 UI Automator API

    前面介绍过根据id,classname, accessibilityid,xpath来定位元素,其他这些方法底层都是利用了 UI Automator 的 API 功能实现的

    UI Automator 介绍

    • UI Automator 测试框架提供了一组 API 来构建 UI 测试,用于在用户应用和系统应用中执行交互
    • 利用 UI Automator API,可以打开“设置”菜单或应用启动器等操作
    • UI Automator 测试框架非常适合编写黑盒自动化测试,其中的测试代码不依赖于目标应用的内部

    UI Automator 提供的功能

    • 自带的元素定位工具
    • 在设备上检索状态信息并执行操作的API
    • 支持跨应用 UI 测试的API

    UI Automator 访问设备状态

    UI Automator 测试框架提供了一个 UiDevice 类,用于在 app 运行的设备上进行访问和执行等操作,它提供了以下操作

    • 更改设备旋转
    • 按D-pad按钮
    • 按返回、主屏幕、菜单按钮
    • 打开通知栏
    • 对当前窗口进行屏幕截图

    更多的 UI Automator API

    利用 UI Automator API,可以编写稳健可靠的测试,而无需了解目标应用的实现详情

    下面将列出常见的类,它们都是在 android.support.test.uiautomator 这个库下的

    类名 作用
    UiDevice 设备封装类 上面说到的,获取设备信息和设备交互
    UiObject 所有空间抽象类 表示设备上可见的一个Android控件
    UiSelector 控制选择器 在设备上查询一个或多个目标 UI 元素
    Configurator 配置基类 设置运行 UI Automator 测试所需的关键参数
    UiScrollable 滚动控件 当目标控件存在于屏幕之外时使用
    UiCollection 控件集合 控件遍历,枚举容器的 UI 元素以便计算子元素个数

    UiSelector 初体验

    java语法

     new UiSelector().resourceId(“io.manong.developerdaily:id/tv_tab_title”) 
    

    结合 Appium 的用法

    driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.hpbr.bosszhipin:id/tv_tab_label")') 
    
    # 此处省略配置代码...
    # 通过resourceId
    test = driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.hpbr.bosszhipin:id/tv_tab_label")')
    print(test.text)
    
    # 通过text
    test = driver.find_element_by_android_uiautomator('new UiSelector().text("附近")')
    print(test.text)
    
    # 通过className
    test = driver.find_element_by_android_uiautomator('new UiSelector().className("android.widget.TextView")')
    print(test.text)
    

    UiSelector 还可以通过哪些方法来定位元素

    方法名 作用
    className(String className) 根据class名称
    classNameMatches(String regex) 根据class名称的正则表达式
    description(String desc) 根据content-desc
    descriptionContains(String desc) 根据content-desc中包含的字符串
    text(String text) 根据文本值text
    textContains(String text) 根据文本值text包含的字符串
    resourceId(String id) 根据resource-id

    基本上除了xpath之外,可以通过appium实现的元素定位方式,UIAutomator也有,因为底层就是靠他实现的

    xpath 虽然没有直接对应的方法,但是像下面这种 xpath 写法,UIAutomator 也有对应的方法

    • // :表示任意后代关系
    • x[n] : 表示第几个子节点
    方法名 对应xpath的语法 作用
    childSelector(UiSelector selector) // 用来选择后代元素(可以是非直接子元素),对应//
    index(int index) *[n] index表示其父元素下的第几个节点
    instance(int instance) 匹配的结果所有元素里面的第几个元素
    比如通过 // android.widget.TextView
    找到了十个对应类型的元素,instance(1) 表示第二个对应的元素,下标是从0开始的
    # 正常appium写法
    
    test = driver.find_elements_by_id("com.hpbr.bosszhipin:id/tv_tab_label")[1]
    
    # 结合uiautomator写法
    
    test = driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.hpbr.bosszhipin:id/tv_tab_label").enabled(true).instance(1)')
    
  • 相关阅读:
    8 Django 模型层(1)
    7 Django的模板层
    Java ClassLoader
    Spring的注入注解
    Java 面试Spring的加载机制
    Spring容器启动初始化bean的方法
    java 线程
    经典博客
    Spring注解@Component、@Repository、@Service、@Controller区别
    java 实现多个文件的Zip包的生成
  • 原文地址:https://www.cnblogs.com/dongye95/p/15027554.html
Copyright © 2020-2023  润新知