前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >appium 元素定位方法总结(一)

appium 元素定位方法总结(一)

作者头像
赵云龙龙
发布2021-04-23 11:15:13
3.9K0
发布2021-04-23 11:15:13
举报
文章被收录于专栏:python爱好部落python爱好部落

在做UI自动化的时候,有一部分精力是定位元素,元素定位得准不准,直接影响自动化的成败和效率。 mobile和web一样,也是通过driver来定位元素的。selenium有8种定位方法,appium有哪些定位方法呢? 常用的方法有:

  1. 通过id定位元素
  2. 通过class_name定位元素
  3. 通过content-desc定位元素
  4. 通过text定位元素
  5. 通过xpath定位元素
  6. 通过uiautomator定位元素,android独有

一般的元素属性有:

  • 使用uiautomator定位 driver.find_element_by_android_uiautomator(uia_string)
  • 根据 resourceId 属性 定位
  • 根据 text、description、className、index属性定位
  • 根据content-desc定位 driver.find_element_by_accessibility_id()
  • 根据xpath定位 driver.find_element_by_xpath()

元素定位

  • find_element_by_xxx符合条件的第一个元素,找不到抛出异常
  • find_elements_by_xxx符合条件的所有元素的列表,找不到返回空列表
  • 通过WebDriver查找范围是整个界面的树形结构
  • 通过WebElement查找的是该节点的子节点
通过id定位元素find_element_by_id
  • 元素的resource-id
  • 唯一标识该元素的值(id有时候并不唯一) 使用前最好先判断下id是否唯一
  • 一般优先根据id定位
代码语言:javascript
复制
# resource-id = 'io.manong.developerdaily:id/edt_phone'
driver.find_element_by_id("io.manong.developerdaily:id/edt_phone")

通过class_name定位元素find_element_by_class_name
  • clsaa属性决定了界面元素的类型
  • 如果我们要查找某种类型的界面元素,且该类型界面元素在当前界面中只有一个,则可以使用此方法
代码语言:javascript
复制
driver.find_element_by_class_name('android.widget.Button')

通过content-desc定位元素find_dlement_by_accessibility_id
  • content-desc属性是用来描述该元素的作用
  • 如果要查询的界面元素的content-desc在当前界面唯一,则可以使用此方法
  • 大部分情况下,该字段为空
代码语言:javascript
复制
driver.find_dlement_by_accessibility_id('test')

通过text定位元素driver.find_element_by_android_uiautomator("text('xxx')")
  • 元素id相同时,可以根据text来进行定位
代码语言:javascript
复制
driver.find_element_by_android_uiautomator("text('热点')")

通过xpath定位元素
  • xpath定位方法可参考:Selenium学习005-元素选择之xpath
  • 当以上方法都无法定位到具体元素时,可以采用xpath方法定位元素
    1. 通过定位工具发现底部几个栏位是同一个class,只有index和界面图标不同
    2. 首先,根据id定位可唯一判断的元素
    3. 然后,找到此唯一元素下级目录汇总class属相对应元素
    4. 最后,取出列表中自己想要的值 注:index从0开始计算,xpath从1开始计算
代码语言:javascript
复制
# 方法一:xpath
xpath = "//*[@resource-id='io.manong.developerdaily:id/tab_layout']//android.widget.RelativeLayout[2]"
driver.find_element_by_xpath(xpath)

# 方法二:xpath+index
xpath = "//*[@resource-id='io.manong.developerdaily:id/tab_layout']//android.widget.LinearLayout//[@index=1]"
driver.find_element_by_xpath(xpath)

实例代码
代码语言:javascript
复制
# coding=utf-8

from appium import webdriver
import time,traceback

desired_caps = {}  # 定义字典:告诉appium我们的一些配置
desired_caps['platformName'] = 'Android'  # 固定值
desired_caps['platformVersion'] = '6'  # android版本
desired_caps['deviceName'] = 'test'  # 连接多个设备时会用到 ?
# desired_caps['app'] = r'/Users/liuhuaiyuan/Downloads/toutiao.apk' # apk在电脑上的路径
desired_caps['appPackage'] = 'io.manong.developerdaily' # apk的package  通过aapt命令查找
desired_caps['appActivity'] = 'io.toutiao.android.ui.activity.LaunchActivity' # 指定apk的启动界面(通常启动界面是唯一的) 通过aapt命令查找
desired_caps['unicodeKeyboard']  = True  # 安装中文输入法,以便于控制,及部分中文的输入
desired_caps['resetKeyboard']  = True  # 针对上一条语句,如果手机还有其他的输入法,还原输入法,便于其他操作
desired_caps['noReset'] = True   # 重要参数,=True 恢复默认值,=False(缺省值) 每次都是从刚安装app的状态进入(格式化状态),可能会显示欢迎页等
desired_caps['newCommandTimeout'] = 6000  # 设置等待时间,当超过这个时间时,将断开与appium的连接。单位是秒
#启动Remote RPC
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps ) # 连接appium,并将参数(字典)传入,执行完此句后,与appium创建一个session
# 0.0.0.0:4723
try:
    driver.implicitly_wait(10)  # 隐式等待,每0.5秒查询一次,直到指定时间,结束。单位是秒

    # 根据id找到元素,并点击,id和 html 元素的id不同
    driver.find_element_by_id("io.manong.developerdaily:id/tab_bar_plus").click()
    time.sleep(1)

    # 定位到密码方式登录
    driver.find_element_by_xpath("//*[@resource-id='io.manong.developerdaily:id/tab_layout']//android.widget.RelativeLayout[2]").click()

    driver.find_element_by_id("io.manong.developerdaily:id/edt_phone").send_keys('xxxxxx')
    driver.find_element_by_id("io.manong.developerdaily:id/edt_password").send_keys('xxxxx')

    time.sleep(2)
    # 点击登录
    driver.find_element_by_id('io.manong.developerdaily:id/btn_login').click()
    pass

except:
    print (traceback.format_exc())

driver.quit()

根据content-desc定位 driver.find_element_by_accessibility_id()

uia_string:uia_string - The element name in the Android UIAutomator library 使用UIAutomator元素属性名称来定位

根据 resourceId 属性 定位

代码语言:javascript
复制
driver.find_element_by_android_uiautomator('new UiSelector().resourceId("%s")')

举例:如下图,点击顶部扫码器:

对应uiautomator名称:“resource-id”:

代码语言:javascript
复制
driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.rfchina.app.supercommunity:id/square_title_btn_scan")').click()

选择resource-id 定位需要特别注意,界面中 resource-id 不是唯一的,有可能存在很多控件的resource-id是相同的。

根据 text、description、className、index属性定位

代码语言:javascript
复制
# 根据 text 定位
driver.find_element_by_android_uiautomator('new UiSelector().text("%s")')  #对应uiautomator名称:“text”

# 根据 description 定位
driver.find_element_by_android_uiautomator('new UiSelector().description("%s")')  # 对应uiautomator名称:“content-desc”

# 根据 className 定位
driver.find_element_by_android_uiautomator('new UiSelector().className("%s")') # 对应uiautomator名称:“class”

# 根据 index 定位
driver.find_element_by_android_uiautomator('new UiSelector().index("%s")') # 对应uiautomator名称:“index”

选择className 定位需要特别注意,界面中 class 往往都不是唯一的,大量控件的class会一样。

根据xpath定位 driver.find_element_by_xpath()

代码语言:javascript
复制
from appium import webdriver
import time

desired_caps = {
    "appPackage": "com.rfchina.app.supercommunity",
    "appActivity": "com.rfchina.app.supercommunity.client.StartActivity",
    "platformName": "Android",
    "deviceName": "Android Emulator"
}

driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
time.sleep(5)
driver.find_element_by_id("com.rfchina.app.supercommunity:id/img_serivce_communities_layout").click()

xpath是最常见的定位方法,虽然性能可能是最慢的,但是它是最万能的。 我们可以用模糊匹配来查找

代码语言:javascript
复制
driver.find_element_by_xpath("//android.widget.TextView[@text='speaking']")

获取toast

代码语言:javascript
复制
driver.find_element_by_xpath("//*[contains(@text,‘toast 信息’)]")

这里只介绍了android的定位方法,ios其实也差不多, 其实IOS中的Type, 相当于android中的class, IOS中的name, 相当于android中的text, 其实IOS中的content_desc, 相当于android中的accessbility_id, 这个后面再讲。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-04-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 python粉丝团 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 元素定位
    • 通过id定位元素find_element_by_id
      • 通过class_name定位元素find_element_by_class_name
        • 通过content-desc定位元素find_dlement_by_accessibility_id
          • 通过text定位元素driver.find_element_by_android_uiautomator("text('xxx')")
            • 通过xpath定位元素
              • 实例代码
              • 根据content-desc定位 driver.find_element_by_accessibility_id()
                • 根据 resourceId 属性 定位
                  • 根据 text、description、className、index属性定位
                  • 根据xpath定位 driver.find_element_by_xpath()
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档