目录

 

一. 元素定位工具

二. 适用范围

三. 原生app定位方式

Appium版本:v1.7.2 

依托语言:python 2.7.15

元素定位平台:Android

一. 元素定位工具

在总结Appium在Androd平台的元素定位方式前,我们首先要做的准备好元素定位工具。要说起Android App的元素定位工具,较为流行的是以下几种:

  1. Android SDK 自带的 uiautomator
  2. Appium 自带的Inspector
  3. Android SDK 自带的 monitor
  4. Chrome 浏览器内置的Devtools

从功能性、易用性和规避被墙的可能角度讲,使用前两种就够用了。

鉴于uiautomator可跨多平台、功能强大、又极易使用,以它作为首选不会令你失望,先到tools文件夹下启动它吧。至于是双击还是命令行,请随意。

Android元素定位绝对路径 安卓定位元素_Appium

看了这个图,是不是再也不用愁找不到元素了,可用的属性太多了!是不是眼花缭乱了,让我们一起来梳理一下。

 

二. 适用范围

我们都知道Appium是基于webdriver做的封装,那么selenium2 中可用的定位方式Appium就都可用了吗?

Android元素定位绝对路径 安卓定位元素_uiautomator_02

回顾一下selenium在web端的强大定位方式群:

  1. id
  2. name
  3. class_name
  4. class
  5. tag_name
  6. link_text
  7. partial_link_text
  8. xpath
  9. css_selector

到了移动端,name、tag_name、link_text、partial_link_text、css_selector,在原生app中就无用武之地了,但它们在H5页聚焦到webview时,依然发挥着强大的功效。其余的在uiautomator中都能找到对应。

 

三. 原生app定位方式

Android元素定位绝对路径 安卓定位元素_uiautomator_03

  1. id定位:对应resource-id属性值

find_element_by_id("resource-id")
find_element(By.ID,"resource-id")
  1. class定位:对应class属性属性值

find_element_by_class("class")
find_element(By.CLASS_NAME,"class")
  1. accessibility_id定位:对应content-desc属性值

element_by_accessibility_id("content-desc")
  1. xpath定位:

  1. (1)绝对路径定位
find_element_by_xpath("/LinearLayout/RelativeLayout/ImageView")
find_element(By.ID,"/LinearLayout/RelativeLayout/ImageView")

(2)相对路径定位

find_element_by_xpath("//mageView")

(3)属性定位

find_element_by_xpath("//ImageView[@属性名]")

这种方式是通过拥有某种属性值来定位,属性可以是text、class、id等。

(4)单/多属性值定位

单属性定位:find_element_by_xpath("//ImageView[@text='text']")
这种方式通过含有特定值的特定属性来定位,属性名可以是text、class、id等。

多属性定位:find_element_by_xpath("///ImageView[@text='text' and @class='android.support.com']")

(5)函数定位

应用于Appium元素定位的xpath函数,比较常见的分为文案匹配、轴定位等。

匹配文案常用的两个函数分别是
contains: find_element_by_xpath("//android.widget.TextView[contains(@text, '发行')]")
startswith: find_element_by_xpath("//android.widget.TextView[startswith(@text, '发行')]")


轴定位函数是一个庞大的群体,他们是一个完整的树形节点的集合。

# 后面兄弟节点定位:定位紧随className=android.widget.ImageView之后第2个类名为android.widget.Button的元素

find_element_by_xpath('//android.widget.ImageView/following-sibling::android.widget.Button[2]')

# 前面兄弟节点定位:定位紧随第二个className=android.widget.Button之后第1个类名为android.widget.Button的元素

find_element_by_xpath('//android.widget.Button[2]/preceding-sibling::android.widget.Button[1]')
  1. uiautomator定位:

  1. (1)精确文案定位
find_element_by_android_uiautomator("new UiSelector().text(\"属性值\")")

(2)模糊文案定位

# 定位包含特定文案元素
find_element_by_android_uiautomator('new UiSelector().textContains("属性值")')
# 定位以特定文案开头的元素
find_element_by_android_uiautomator('new UiSelector().textStartsWith("属性值")')
# 定位匹配特定文案的元素
find_element_by_android_uiautomator('new UiSelector().textMatches("^属性值*")')

(3)id定位

find_element_by_android_uiautomator("new UiSelector().resourceId(\"resource-id\")")
find_element_by_android_uiautomator('new UiSelector().resourceIdMatches("^resource-id*")')

(4)class定位

find_element_by_android_uiautomator("new UiSelector().className(\"className\")")
find_element_by_android_uiautomator('new UiSelector().classNameMatches("^className*")')

(5)description定位

# 定位包含特定描述元素
find_element_by_android_uiautomator('new UiSelector().descriptionContains("描述")')
# 定位以特定描述开头的元素
find_element_by_android_uiautomator('new UiSelector().descriptionStartsWith("描述")')
# 定位匹配特定描述的元素
find_element_by_android_uiautomator('new UiSelector().descriptionMatches("^描述*")')

(6)fromParent兄弟节点定位

# resourceId = com.hande.chain.wallet:id/create的节点是目标节点的兄弟节点——同层级,同父节点
# 先定位到兄弟节点,再通过目标节点的text属性定位
find_element_by_android_uiautomator('new UiSelector().resourceId("com.hande.chain.wallet:id/create").fromParent(text("导入"))')
# 先定位到兄弟节点,再通过目标节点的resourceId属性定位
find_element_by_android_uiautomator('new UiSelector().resourceId("com.hande.chain.wallet:id/create").fromParent(resourceId("com.hande.wanchain.wallet:id/recover_wallet"))')

uiautomator中的fromParent方法与xpath中的preceding-sibling、following-sibling方法等效

(7)childSelector父子节点定位

# className = android.widget.RelativeLayout的节点是目标节点的父节点
find_element_by_android_uiautomator('new UiSelector().className("android.widget.RelativeLayout").childSelector(resourceId("com.hande.wanchain.wallet:id/recover"))')

(8)组合定位

find_element_by_android_uiautomator("className(\"className\").text(\"next\")") ——类似于xpath中的[@class='x' and @text='y']通过多个确定属性定位

(9)集合定位

element='new UiSelector().text("属性值")'
driver.find_element_by_android_uiautomator(element)[2].click() 
——如果所用定位属性值不唯一,可先获取等于特定值的元素,再用索引来指定哪个元素。

也许有小伙伴儿要问了,还有哪些属性可以用呢?只要是uiautomater能查看到的定位工具都可通过这种方式使用,只是名称可能有些许变化,比如resource-id要用resourceId代替。

  1. 坐标定位:对标bounds属性值
tap([X,Y)]) X,Y分别为点的X坐标和Y坐标,此方法是通过点坐标定位并执行短按