Appium Appium - iOS 定位方式 iOSNsPredicateString 详解

wenshi11019 · 发布于 2017年07月19日 · 最后由 wenshi11019 回复于 2017年08月18日 · 1401 次阅读
本帖已被设为精华帖!

iOS 定位方式 iOSNsPredicateString 详解

前言

由于使用idclassNameAccessibilityId定位方式较为简单,多数情况下,在同一个页面,都不是唯一存在的,不能识别一个元素。而 xpath定位方式在 xcui 底层原生不支持,由 appium 额外支持的,定位速度很慢,而且有时候定位不到元素的情况存在。综上所述,在 iOS 的 UI 自动化中,使用原生支持的iOSNsPredicateString定位方式是最好,支持也是最好的。

定位方式

iOS 版本全支持,底层测试框架无论是 XCUITest 或 UIAutomation,可支持元素的单个属性和多个属性定位,推荐使用。一个元素有这些属性:typevaluenamelabelenabledvisible,有些元素的属性只有以上的部分属性,如下图所示,可根据这些属性进行元素定位。

元素属性的介绍

type:元素类型,与className作用一致,如:XCUIElementTypeStaticText
value: 一般不用
name:元素的文本内容,可用作 AccessibilityId定位方式,如:测试420班级群
label:绝大多数情况下,与 name 作用一致
enabled:元素是否可点击,一般值为true或者false
visible:元素是够可见,一般值为true或者false

定位方式

元素的定位方式都是一个属性+运算符+值形式存在

  1. 比较运算符:>,<,==,>=,<=,!=
    可用于数值和字符串的比较,
    如:name>100name == '测试'

  2. 范围运算符:IN,BETWEEN
    可用于数值和字符串的范围核对
    如:name BETWEEN {3,10}name IN {'Alan','May'}

  3. 字符串相关:CONTAINSBEGINSWITHENDSWITH
    包含某个字符串,如:label CONTAINS '测试'
    以某个字符串开头,如:label BEGINSWITH '420'
    以某个字符串结束,如:label ENDSWITH '班级群'
    PS:在三个关键字后加上[c]不区分大小写,可用于字母的校验;[d]不区分发音符号,即没有重音符号($、#、%等);[cd]即不区分大小写,也不区分发音符号,如:name CONTAINS[c] ABcdname CONTAINS abcdname CONTAINS ABCD是等同的,注意后面两个没带[c]的不相等

  4. 通配符:LIKE
    通配符也接受[cd]?代表一个字符,*代表多个字符
    如:一个元素的label属性为

    label LIKE '420测试班级群'
    label LIKE '420测?班级群'
    label LIKE '420??班级群'
    label LIKE '42?测试班?群'
    label LIKE '*试班级群'
    label LIKE '420测试班*'
    label LIKE '42*级群'
    label LIKE '4*试*群'
    

    以上这么多种文本都可以被识别为同一个元素。

  5. 正则表达式:MATCHES
    如:以4开头,以结束,

    label MATCHES '^4.+群$'
    

    PS:具体正则表达式语法,请百度一下,你就知道

以一种属性定位元素

可以用元素的属性:typevaluenamelabelenabledvisible,进行定位:

type == XCUIElementTypeStaticText,
label CONTAINS '测试'
label LIKE '*试班级群'
enabled == true
visible == false

以两种或两种以上属性定位元素

就是以上单个属性定位用符号AND连接起来即可。如:

type == XCUIElementTypeStaticText AND label CONTAINS '测试
type == XCUIElementTypeStaticText AND label CONTAINS '测试' AND enabled == true
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 38 条回复
4845 wenshi11019 Appium-同一个元素不同定位方式的区别 中提及了此贴 07月19日 09:38
4845 wenshi11019 appium python 脚本 xpath 报错,求指点 中提及了此贴 07月19日 09:39
Fe45d1

写得很详细,好评~ 不过iOS Predicate在iOS10以下也支持哒

NOTE: iOS predicates are usable in iOS 9.3 and below using the -ios uiautomation locator strategy and they are usable in iOS 10 and above using the -ios predicate string locator strategy

921230

特别好,值得参考,不过有个问题还想请教一个问题:sdk '10.1.1' was not in list of simctl sdks
这个问题解决了,反复出现,大家有没有遇到

4845
Fe45d1JoTsai 回复

我的错,9.3以下版本没用过,不敢确认,现在我去修改下,感谢指正啊😁

4845 wenshi11019 关闭了讨论 07月20日 09:44
4845 wenshi11019 重新开启了讨论 07月20日 09:44
104 seveniruby 将本帖设为了精华贴 07月20日 21:04
104

小而美的文章

77d9c0

能举个appium里使用python编写的脚本例子吗,谢谢

15271

“xpath定位方式在 xcui 底层原生不支持” 楼主这句话的意思是iOS10以上都不支持xpath定位吗?

4845
15271iSteven 回复

不是,在 Appium 和 Macaca 上都支持 xpath 定位,但是这不是底层本身支持的,会有缺陷的

4845
77d9c0913616672 回复

我在用 java,python 不怎么会啊

5210

学习了,最近马上要弄这一块东西,提前了解下😀

77d9c0
4845wenshi11019 回复

java也行啊,嘿嘿😀

4457

type == XCUIElementTypeStaticText不一定能定位到你想要的那个text吧?

214

请问楼主,这个 iOSNsPredicateString 工具 需要单独下载吗

4845
4457testerwp 回复

如果一个页面,只有一个XCUIElementTypeStaticText,就会定位到。如果多个,就会定位在页面第一个XCUIElementTypeStaticText

4845
214oscar 回复

这是 appium 本身支持的一种定位方式,不需要重新下载,在代码使用就可以

4845
104seveniruby 回复

谢谢大神,以后会努力发帖😁

214
4845wenshi11019 回复

我看你有几个截图 是用啥打开的

4845
214oscar 回复

Appium Desktop,新的 appium 客户端

5210

这种定位方式其实就是根据元素的属性进行定位,但是页面上很多的元素的属性其实基本上是一样的,对于这种元素有没有好的办法进行定位呢

4457
5210darkmanno6 回复

相同属性的元素可以生成一个List,然后根据index定位

5210
4457testerwp 回复

如果页面元素很多的话,其实也不是很好判断这个List有多大以及这个元素在List中的位置吧,难道要先打印出来list再来定位吗?

4845
5210darkmanno6 回复

ios 有些元素是获取不了 text 的值,一般都是将相同的元素生成一个 List,或者在编写用例的时候,强制使用其中一个元素

5210
4845wenshi11019 回复

好吧,最近才开始搞这个ios自动化,相较android而言,确实繁杂许多啊😂

4845
5210darkmanno6 回复

对的,比 android 繁琐好多,很多限制,ios 整个生态决定,没有办法啊

8331

你好 可以举一个简单的例子吗 这个是通过findby 什么定位的 我在 findby列表下没有找到你说的这个定位方式 请指教谢谢

69ae3c

@sysayy 楼主的这个方式应该就是appium里面的findbyid/type
ios底层对id name AccessibilityId是相同的处理

5210
4845wenshi11019 回复

我现在使用iOSNSPredicateString的时候发现一个诡异的情况,总是会有发生找不到元素的情况,使用隐式等待也没用,只能到页面之后sleep显示等待才能找到,而xpath基本上能找到,你有碰到过吗?

4845
5210darkmanno6 回复

遇到过,这个的原因估计是查找元素的动作过后,页面才显示元素。xpath 没事,因为 xpath 速度比较慢。所以这种情况下最好封装下元素查找,让元素在某段时间内,不断地循环查找

4845
8331sysayy 回复

有的,就是FindsByIosNSPredicate

5210
4845wenshi11019 回复

现在用的pagefactory初始化页面元素的,不是很好封装😭

4845
5210darkmanno6 回复

这个没怎么用过

10714

请教个问题,我们在用appium做iOS端的自动化测试,想通过给控件添加accessibilitylabel的方法实现find_element_by_accessibility的方式获取控件,现在遇到的问题是加完上面的属性后,空间的value,name,label属性的值都变成了我们添加的accessibilitylabel,请问原因是什么啊?

1ef498
4845wenshi11019 回复

请教一下,我用了type == XCUIElementTypeCell查找;在页面中有很多个XCUIElementTypeCell;照您的逻辑是找到第一个,我想要的也是第一个cell;可是我这边是直接找不到;然后开始重试;想问一下是怎么回事?

4845
1ef498_Aaron 回复

先仔细看看你的页面第一个 cell 是不是你想要那个?有时候第一个 cell 在列表之外

4845
10714myzle 回复

value,name,label这三个属性本来就一致的啊

10714
4845wenshi11019 回复

额,我可能没描述清楚,我添加了accessibilitylabel后,value,name, label这三个属性都显示成了ID的值,但是控件本身是有文本信息的,文本信息如何获取?

4845
10714myzle 回复

你是要先获取元素,再获取文本值?

10714
4845wenshi11019 回复

是的,先获取元素,再获取文本,文本是根据数据动态加载的

4845
10714myzle 回复

appium 的 api 应该有一个元素的 getText()方法的。你可以试试

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册