Appium之「元素定位和UiAutomator表达式」

作者:清菡
博客:oschina、云+社区、知乎等各大平台都有。

目录

  • 一、常见属性的用法
    • 1.怎么用 resource-id?
    • 2.其它属性
  • 二、通过截图就可以看到元素的属性,那怎么元素定位呢?
    • 1.appium - app 页面元素定位
    • 2.UiAutomator 的表达式
    • 3.什么时候用 UiAutomator 呢?
    • 4.和 Web 自动化的定位有啥区别?
  • 三、问题
    • 1.元素与属性的区别?
    • 2.app 一进模拟器就崩溃
    • 3.如果遇到点击 uiautomatorviewer 就闪退

一、常见属性的用法

xpath 相对定位:如果相对定位中这个元素是有 id 的,这个 id 是唯一的,xpath 定位中优先通过 id 来定位。

class 属性对应的值是元素类型(是一个文本视图工具),Web 自动化中元素类型代表 Input、image、button 这样的标签名。

1.怎么用 resource-id?

「resource-id 是唯一的,但是在 App 页面中并不绝对唯一。大部分情况下是唯一的,小部分情况下是重复的。」

如果一个页面中,元素的样式非常像,那很有可能它们的 id 就是一样的。UIAutomator Viewer 这个自带的工具是不能看出这个 id 是不是绝对唯一的。

「假设 resource-id 是唯一的,用相对定位这样定位:」

和 Web 自动化一样的玩法:元素类型[@属性名称=属性值]

这里的 class 不是 Web 网页中的 class 属性了,这里代表它的标签名和元素类型(它是一个图片、一个文字、链接还是一个按钮呢?学会区分)。

如果 resource-id 不是唯一的,那么上面那个表达式是不够的,还会追加到上层的 LinearlayoutRelativeLayout、包括祖先里面的一些层级都会放进来。

如果没有安装“升级 uiaumatorview-添加元素定位”就只能靠自己来判断。看下其它和它长得很像、元素的格式、风格、样式、页面布局都和它一模一样的元素,看下各位的 id 是否全都是一样的。

如果用了“升级 uiaumatorview-添加元素定位”,可以根据它的表达式自己来判断。

任何一个元素一定会有个 class,因为它是一个类别。Linearlayout 是一样的,布局也是安卓的控件,所以也会有控件名称、控件类型。

以下这些东西只有 2 个值,False 和 True。

2.其它属性

以上这些属性在很多情况下是没有用的,但是在关键的时刻是很有用的。

例如想筛选当前页面中可以滚动的元素,通过 scrollable 等于 True 来过滤。

二、通过截图就可以看到元素的属性,那怎么元素定位呢?

和 Web 自动化一样的,都是通过元素属性来定位,而且比 Web 自动化简单。

App 中只支持 5 种元素定位方式。虽然继承了 Web 自动化的元素定位,它之所以继承呢,是用到了其中的一个部分。

1.appium - app 页面元素定位

1、通过 id 定位元素:resrouce-id
2、通过 ClassName 定位:classname
3、通过 AccessibilityId 定位:content-desc
4、通过 AndroidUiAutomator 定位
5、通过 xpath 定位

与 Web 自动化通用的是 3 种:

1、通过 id 定位元素:resrouce-id
2、通过 ClassName 定位:classname
3、通过 xpath 定位

1.1通过 id 定位元素:resrouce-id
#id
driver.find_element_by_id('保密')

find_element_by_id()就有find_elements_by_id()

可以找到多个,它的返回值一样是列表。它的返回对象一样是 Web element

源码:

来自于这个文件:

在它的下面有个find_element_by_id()。它的方法和 Web 自动化是一样的。

1.2第二种定位方式 ClassName,ClassName 就是这里的 class 属性。

虽然这里代表的是元素类型,但它同样是 class 属性。

所以用这种方法就是这样写:
#classdriver.find_element_by_class_name('保密')

这里有点区别,但是方法名还是没有区别的。这个 class 的属性其实没有多大用处,一个页面中肯定很多属性的值和它很像的。所以这种用法不多。

既然是类别,图片可能有好多种,输入框也有好多种,它代表的是一种元素的类型。

「Web 自动化中 xpath 定位是最常用的,但是 App 自动化中 xpath 是最不想用的。原因是它的效率太低了。」

「如果全部只用 xpath 定位,问题会比较大,能不用 xpath 就不用 xpath」

1.3通过 AccessibilityId 定位

AccessibilityId 是移动端特有的定位方式。

from appium.webdriver.common.mobileby import MobileBy

这是之前看到的类,这个类当中除了继承了 Web 自动化之外,对于安卓有 2 种,其中一种是ACCESSIBILITY_ID

源码如下:

如果通过这种方式定位,对应的方式就是:

#content-descdriver.find_element_by_accessibility_id()

此处应输入 content-desc 的值,但是这里是空的,所以不能通过它定位。

但是find_element_by_accessibility_id()是另外一种 id,代表它在当前这个页面中也是很独特的。只要它有值,基本上可以通过它来定位。

1.4通过 AndroidUiAutomator 定位

用的是安卓 UiAutomator 这个自动化框架中提供的元素定位方式。所以想用这种元素定位方式,就必须了解它到底是怎么做的。

UiAutomator 自动化库是 Java 语言写的,所以它的参数是 Java 代码。UiAutomator 自动化库提供了 text。而「元素有文本内容就可以通过文本内容来定位。」

这个里面的参数就必须是 UiAutomator 当中提供的定位方式。UiAutomator 是 Java 实现的,那么它的定位类型肯定也是 Java 实现的。

这个是谷歌开发中心的网址,有对 UiAutomator 的介绍:

https://developer.android.com/training/testing/ui-automator.html#ui-automator-viewer

UiAutomator 去定位元素的时候用的 UiSelector 类。Api 的官方文档:

Appium 中通过 driver.find_element 来找元素的,找到的结果对象是一个 WebEmemt

「但是括号里面,不同的定位类型你要输入不同的定位表达式。」

UiSelector 是个 Java 类,主要用来做元素定位表达式。什么来代表 UiSelector 中的 WebEmemt 呢?

通过 UiSelector 找到元素,这是表达式。总有一个方法通过它来找吧?

那就是 UiObject。UiObject 对应到 WebEmemt。WebEmemt 有对元素的各种操作以及属性的获取。「UiObject 就是 WebEmemt,有各种对元素的操作。」

UiObject 就可以获取这么多的属性:

通过 UiObject 对元素进行输入、点击等操作。

UiAutomator 是它自己的框架,所以对应的做了一套东西。UiSelector 这个类是用来表达元素定位的。UiAutomator 这里的参数就是 UiSelector 类定位表达式。

Public constructors 公共的构造函数,构造函数就是初始化函数。类初始化的时候,有时候 init 是有参数的,构建函数当中就告诉了你它有没有参数。

初始化的表达式:

UiSelector()

Java 中这样写:

new ui= UiSelector() 这就是代表类的实例化。

python 中这样写:

ui = UiSelector()

简写的做法:

new UiSelector()

有的时候并不用一个变量去接收它。在 Web 自动化当中,直接实例名称.方法就可以了。

在 Java 中不需要用一个变量去接收实例化对象,那就直接这样写new UiSelector().后面调它的各种方法。Java 中每一个变量必须声明变量类型,它是个布尔值,是个类还是什么。

事实上只有一个变量,叫做 val。

在这个地方,类也算一种数据类型。在 Python 中,类也算一种数据类型,是你自己构造的这种数据类型,只不过不需要声明而已。

清一色的返回值基本都是类本身。

如果是一个实例化对象,那它的返回值都是实例化对象。每一个实例化对象都可以有这么多方法。

.checkable(true)返回值就是new UiSelector()。接下来可以通过别的方式组合起来。

「多种条件组合起来对元素进行定位。有些元素的 id 不是唯一的,但是文本是唯一的。可以纯粹通过文本,也可以 id 和文本一起定位。」

resourceId 有 2 种方式:

「人家这里是“字符串”,在 Java 中单引号和双引号是有区别的。如果在 Java 中是字符串,只能用双引号,不然就是报错。」

new UiSelector().checkable(true).resourceId(“保密”)

通过 2 个属性来定位的,一个是 checkable()。

一个是 resourceId()。两者都要满足才能符合我的定位表达。

匹配到正则表达式的元素也可以。

text 提供了 4 种定位方式:

第一种:全局匹配(完全文本匹配)。

new UiSelector().checkable(true).resourceId(“保密”).text(“我的”)

第二种:包含。

第三种:正则表达式的匹配。

textstartswith:以什么开头的一个字符串。

如果你的文本很长,可以定义以什么开头,也可以实现部分匹配。只不过这个部分匹配是有要求的,必须以什么开头。

这 4 种方式都可以用的,参数全是字符串。

除了 text 是文本性质的,content-desc 也是文本性质的。

content-desc 也提供了 4 种定位方式:

className:匹配一个控件的类型。

控件类型也属于控件的属性。大家都叫做控件,但是你叫这个名字,我叫那个名字。

每个元素的 package 都是一样的,所以 package 没多大用处。

scrollable:除了 UiAutomator 可以提供到位,xpath 也可以做到但是有所欠缺。

UiAutomator 自动化库提供了各种属性。只要学会表达式,然后能自己判断用什么样的类型来定位就好了。

2.UiAutomator 的表达式

使用 UiAutomator 中的 UiSelector 类来处理元素定位。

new UiSelector().函数名称(“定位表达式”)

字符串是双引号,布尔值就不是双引号了。

driver.find_element_by_android_uiautomator('new UiSelector().resourceId('保密').text('我的')')#这种用法,外面只能用单引号或者里面的双引号打个斜杠标明下

实际上只通过 text 定位就可以了。除了它叫做”我的“,这个页面也没有别人叫做”我的“了。

所以改成这样:
# UiAutomatordriver.find_element_by_android_uiautomator('new UiSelector().text('我的')')#这种用法,外面# 只能用单引号或者里面的双引号打个斜杠标明下

3.什么时候用 UiAutomator 呢?

「如果通过 id 定位、ClassName 定位、AccessibilityId 定位这前 3 种方式都没有让你唯一定位到元素,那就用第 4 种呀!」

第 4 种其实效率很高的,因为是人家框架自己的定位方式呀,都不需要转换。第 5 种 xpath 定位,写法其实和 Web 自动化的 xpath 定位的写法一样。xpath 能干的事,第 4 种方式就能全部搞定了。

以上 5 种都搞不定的情况下,就需要用坐标了。但是坐标不太稳定,除非实在没有办法了才用坐标,坐标比 xpath 还差劲。

一般的 app 都有 id,如果你测得 app 没有 id,那就去给开发提意见,把 id 加上。

4.和 Web 自动化的定位有啥区别?

app 自动化相对来说比较简单。如果把“uiaumatorview 升级版”装上了,所有的定位表达式就直接拷贝就好了。

「不需要调试也不需要考虑上下级关系,如果是比较规范的 app,通过 id 来定位就可以了。」

和 Web 自动化的写法一样。4 大属性都一样(点击、输入、获取元素的文本内容、获取元素的属性)。函数名称一样,操作方式也一样。需要等待,等待方法也和 Web 自动化一样。

三、问题

1.元素与属性的区别?

元素:

一对(或一个)标签包含的范围:其实可以理解为元素为一个容器,而这容器里面包含了标签。

这里的一对标签:<body> </body>就是开始和结束标签。

范围:就是从开始标签<body>到结束标签</body> 下面那个矩形框架就是这里的范围。

(0)

相关推荐

  • appium+python自动化58-xpath定位

    基本属性定位 以淘宝app为例,定位左上角扫一扫按钮 1.可以通过text文本定位到 //*[@text='text文本属性'] # 定位text driver.find_element_by_xpa ...

  • selenium定位不到元素常见的问题

    selenium定位不到元素常见的问题

  • uiautomator2+python自动化测试2-抓元素利器weditor

    前言 android sdk里面自带的uiautomatorviewer.bat可以查看手机app上的元素,但是不太好用,网上找了个大牛写的weditor,试用了下还是蛮不错的 python环境:3. ...

  • selenium基础:元素定位的8种方法

    元素定位一共有8种方法id唯一的name元素的名称class name元素的类名tag name标签,不推荐,重复率太高link text文本链接partial link text对文本链接的一种补充 ...

  • scrapy中Xpath表达式总结

    xpath是一门在XML文档中查找指定信息的标记语言,可以对XML文档中的元素和属性使用路径表达式来进行定位(导航). xpath常用语法 /          选择某个标签下的所有内容 text() ...

  • 这样教都不会?还得我亲自出马!

    来源:Python 技术「ID: pythonall」 上次说到了还有别的方法能找到搜索框吗?答案是当然有了.而且为了满足大部分场景,有很多方法可以定位元素.今天就来继续跟大家一起学习下 Python ...

  • 2.4元素定位xpath_css

    xpath和css定位基础

  • 定位元素 | 白月黑羽教Python

    代码规则 点击这里,边看视频讲解,边学习以下内容 从示例代码,大家就可以发现,和Selenium Web自动化一样,要操作界面元素,必须先 定位(选择)元素. Appium是基于Selenium的,所 ...

  • uiautomator2 ​元素定位

    表白:我听着你的笑话,笑着笑着就哭了 讲解对象: uiautomator2 元素定位  作者:融水公子 rsgz 元素定位方式1  text文本 import uiautomator2 as u2# ...

  • Appium+python自动化12-appium元素定位

    前言 appium定位app上的元素,可以通过id,name.class这些属性定位到 一.id定位 1.appium的id属性也就是通过UI Automator工具查看的resource-id属性 ...

  • 史上最全!Selenium元素定位的30种方式

    Selenium对网页的控制是基于各种前端元素的,在使用过程中,对于元素的定位是基础,只有准去抓取到对应元素才能进行后续的自动化控制,我在这里将对各种元素定位方式进行总结归纳一下. 这里将统一使用百度 ...

  • Appium+python自动化28-name定位

    前言 appium1.5以下老的版本是可以通过name定位的,新版本从1.5以后都不支持name定位了 一. name定位报错 1.最新版appium V1.7用name定位,报错: > sel ...

  • appium+python自动化30-list定位(find_elements)

    前言 有时候页面上没有id属性,并且其它的属性不唯一,平常用的比较多的是单数(element)的定位方法,遇到元素属性不唯一,就无法直接定位到了. 于是我们可以通过复数(elements)定位,先定位 ...

  • appium+python自动化31-android_uiautomator定位

    前言 appium的前身就是封装android的uiautomator这个框架来的,所以uiautomator的一些定位方法也可以用 一. text 1.通过text文本定位语法 > new U ...

  • appium+python自动化32-android_uiautomator定位进阶版

    前言 上一盘介绍uiautomator的定位方式都是类似这种'new UiSelector().xxx("xxx")',看起非常长,我也记不住,这很不python.于是本篇优化了定 ...

  • 关于面试总结10-selenium中隐藏元素定位

    前言 面试题:selenium中隐藏元素如何定位?这个是很多面试官喜欢问的一个题,如果单纯的定位的话,隐藏元素和普通不隐藏元素定位没啥区别,用正常定位方法就行了 但是吧~~~很多面试官自己都搞不清楚啥 ...

  • Cypress web自动化28-运行器界面调试元素定位和操作

    前言 Cypress提供了一个很好的测试运行器, 它为你提供了一套可视化结构的测试和断言套件, 很快你也会看到命令, 页面事件, 网络请求等. 当你还没熟练掌握元素定位时,在运行器界面点开探测器,会自 ...