Appium Appium – iOS 定位方式 iOSNsPredicateString 详解

。
订阅者
270
文章
0
评论
测试交流1 181字数 786阅读2分37秒阅读模式

iOS 定位方式 iOSNsPredicateString 详解

前言

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

定位方式

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

Appium
 Appium – iOS 定位方式 iOSNsPredicateString 详解插图
文章源自玩技e族-https://www.playezu.com/179774.html

元素属性的介绍

type:元素类型,与className作用一致,如:XCUIElementTypeStaticText
value: 一般不用
name:元素的文本内容,可用作 AccessibilityId定位方式,如:测试420班级群
label:绝大多数情况下,与 name 作用一致
enabled:元素是否可点击,一般值为true或者false
visible:元素是够可见,一般值为true或者false文章源自玩技e族-https://www.playezu.com/179774.html

定位方式

元素的定位方式都是一个属性+运算符+值形式存在文章源自玩技e族-https://www.playezu.com/179774.html

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

    文章源自玩技e族-https://www.playezu.com/179774.html

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

    文章源自玩技e族-https://www.playezu.com/179774.html

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

    文章源自玩技e族-https://www.playezu.com/179774.html

  4. 通配符:LIKE
    通配符也接受[cd]?代表一个字符,*代表多个字符
    如:一个元素的label属性为文章源自玩技e族-https://www.playezu.com/179774.html

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

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

    文章源自玩技e族-https://www.playezu.com/179774.html

  5. 正则表达式:MATCHES
    如:以4开头,以结束,文章源自玩技e族-https://www.playezu.com/179774.html

    label MATCHES '^4.+群$'
    

    PS:具体正则表达式语法,请百度一下,你就知道文章源自玩技e族-https://www.playezu.com/179774.html

以一种属性定位元素

可以用元素的属性: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
 
    • JoTsai
      JoTsai 9

      写得很详细,好评~ 不过 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
      特别好,值得参考,不过有个问题还想请教一个问题:sdk ‘10.1.1’ was not in list of simctl sdks
      这个问题解决了,反复出现,大家有没有遇到我的错,9.3 以下版本没用过,不敢确认,现在我去修改下,感谢指正啊 小而美的文章能举个 appium 里使用 python 编写的脚本例子吗,谢谢“xpath 定位方式在 xcui 底层原生不支持” 楼主这句话的意思是 iOS10 以上都不支持 xpath 定位吗?不是,在 Appium 和 Macaca 上都支持 xpath 定位,但是这不是底层本身支持的,会有缺陷的我在用 java,python 不怎么会啊学习了,最近马上要弄这一块东西,提前了解下 java 也行啊,嘿嘿 type == XCUIElementTypeStaticText 不一定能定位到你想要的那个 text 吧?请问楼主,这个 iOSNsPredicateString 工具 需要单独下载吗如果一个页面,只有一个 XCUIElementTypeStaticText,就会定位到。如果多个,就会定位在页面第一个 XCUIElementTypeStaticText这是 appium 本身支持的一种定位方式,不需要重新下载,在代码使用就可以谢谢大神,以后会努力发帖 我看你有几个截图 是用啥打开的Appium Desktop,新的 appium 客户端这种定位方式其实就是根据元素的属性进行定位,但是页面上很多的元素的属性其实基本上是一样的,对于这种元素有没有好的办法进行定位呢相同属性的元素可以生成一个 List,然后根据 index 定位如果页面元素很多的话,其实也不是很好判断这个 List 有多大以及这个元素在 List 中的位置吧,难道要先打印出来 list 再来定位吗?ios 有些元素是获取不了 text 的值,一般都是将相同的元素生成一个 List,或者在编写用例的时候,强制使用其中一个元素好吧,最近才开始搞这个 ios 自动化,相较 android 而言,确实繁杂许多啊 对的,比 android 繁琐好多,很多限制,ios 整个生态决定,没有办法啊你好 可以举一个简单的例子吗 这个是通过 findby 什么定位的 我在 findby 列表下没有找到你说的这个定位方式 请指教谢谢@sysayy 楼主的这个方式应该就是 appium 里面的 findbyid/type
      ios 底层对 id name AccessibilityId 是相同的处理我现在使用 iOSNSPredicateString 的时候发现一个诡异的情况,总是会有发生找不到元素的情况,使用隐式等待也没用,只能到页面之后 sleep 显示等待才能找到,而 xpath 基本上能找到,你有碰到过吗?遇到过,这个的原因估计是查找元素的动作过后,页面才显示元素。xpath 没事,因为 xpath 速度比较慢。所以这种情况下最好封装下元素查找,让元素在某段时间内,不断地循环查找有的,就是 FindsByIosNSPredicate现在用的 pagefactory 初始化页面元素的,不是很好封装 这个没怎么用过请教个问题,我们在用 appium 做 iOS 端的自动化测试,想通过给控件添加 accessibilitylabel 的方法实现 find_element_by_accessibility 的方式获取控件,现在遇到的问题是加完上面的属性后,空间的 value,name,label 属性的值都变成了我们添加的 accessibilitylabel,请问原因是什么啊?请教一下,我用了 type == XCUIElementTypeCell 查找;在页面中有很多个 XCUIElementTypeCell;照您的逻辑是找到第一个,我想要的也是第一个 cell;可是我这边是直接找不到;然后开始重试;想问一下是怎么回事?先仔细看看你的页面第一个 cell 是不是你想要那个?有时候第一个 cell 在列表之外value,name,label 这三个属性本来就一致的啊额,我可能没描述清楚,我添加了 accessibilitylabel 后,value,name, label 这三个属性都显示成了 ID 的值,但是控件本身是有文本信息的,文本信息如何获取?你是要先获取元素,再获取文本值?是的,先获取元素,再获取文本,文本是根据数据动态加载的appium 的 api 应该有一个元素的 getText() 方法的。你可以试试发现个问题,不知道是不是个例,我用 iOSNSPredicate 定位一个不在当前屏的元素然后进行点击操作,它居然没有抛 NosuchElement 的异常但也没有点击成功就这么过去了,看日志也没有什么异常抛出。inspector 一下当前屏的元素,看看有没有你所点击的那个元素。如果有,iOSNSPredicate 定位肯定没问题的。但因为那个元素不在当前屏,所以肯定没办法点击成功,你试试用其他方式定位那个元素,看看是不是也没有报错element visible = false , 你把 location(x,y),打印下,是不是变成(0,0)了发现如果当前页面超过一屏,使用 inspector 能解析到屏幕以外的元素,而且 isvisible 以及 enable 都是 true,所以 findElement 的时候没有跑出 nosuchelement 的异常,但是不在当前屏幕上所以点击肯定是没效果的。有点误解啊。。我打印了下元素的信息如下,确实坐标 (0,0),isDisplayed 为 false,但是 inspector 上的 isVisible 是 true
      所以判断元素是否可用,可以用 isdisplayed 这个方法,而不是直接定位inspector 不是很准确的,你可以在定位 element 的时候,加上 visible = true嗯,加了之后就可以了,被 inspector 误导了,谢谢客气了正好最近在学这个,太及时,先赞再看。谢谢了先。为什么我的 appium 没有 iOSNsPredicateString 这个定位方式java-client 版本低我导入了一个 Java-client5.0 的,也还是没有。但是我的 4.1.2 版本没有删除,一旦删除 4.1.2iosdriver 就会报错说明你还是用的 4.1.2好的,谢谢你!你好,我从 Java-client 5.0 的 beta1 一直试到 beta9 然后又用的 java-client 5.0.1 和 5.0.2 也还是没有 driver.findElementByIosNsPredicate。。。可以给个你的那个 jar 包吗?十分感谢你的 driver 一定要是 iosDriver 才能用的,不然不能用是 iosDriver,而且我在我的 io.appium.java.client 下也找到了 findElementByIosNsPredicate。但是就是不能调用我用的是 eclipse,请问您用的是什么框架我用的是 IDEA,不过这个应该不跟 IDE 有关系才对啊。你这个要好好看下你的代码才行了大神这怎么安装?怎么驱动的?不用另外安装啊,这个 Appium 本身就支持的那是怎么打开这个界面的。是 appium 点击 start session。然后启动完会出现的界面么对的,但还是要填写参数大神我配置好了参数,start session 后 ,但是 inspector 没有截图显示,无法看到对应元素(app 已被驱动开):[debug] [iProxy] Error connecting to device![debug] [JSONWP Proxy] Proxying [GET /screenshot] to [GET http://localhost:8100/session/CDBB28E1-F406-4F6C-AD5C-640A477B63A9/screenshot] with no body[error] [MJSONWP] Encountered internal error running command: ProxyRequestError: Could not proxy command to remote server. Original error: Error: socket hang up
      at JWProxy.proxy$ (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/appium-base-driver/lib/jsonwp-proxy/proxy.js:153:13)
      at tryCatch (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:67:40)
      at GeneratorFunctionPrototype.invoke as _invoke
      at GeneratorFunctionPrototype.prototype.(anonymous function) as throw
      at GeneratorFunctionPrototype.invoke (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:136:37)
      [info] [HTTP] <– GET /wd/hub/session/0168ffd7-d357-4d0d-94e2-a3d16c5be10b/screenshot 500 17254 ms – 250 [info] [XCUITest] xcodebuild exited with code ’65’ and signal ‘null’你这是环境没配置好吧可以了 我的 Appium 版本有问题 我下载了最新的就好了 那大神 你说的是元素定位 那具体的动作呢?比如 click(),有没有个参考例子呢?带动作的那种元素定位和动作没分开的,动作具体要看这个元素是设什么类型,文本框,按钮还是其他@xiaoyuezuibang 你的问题解决了没?我也遇到相同问题。能说下方法吗?这个是只有 appium 支持吗?使用 macaca 没有看到对应的 api,XCTestWD version: 1.3.1,应该是没有问题的吧应该都支持的,有些地方可能需要改改,你可以试试具体怎么用,能给个完整的例子么刚入门不久,看到这篇文章涨知识了请问用谓词代替 Xpath 怎么用?我试了一下报错:WebElement 不能隐式的转换成 IosElement、工厂模式:@iOSXCUITFindBy(iOSNsPredicate = sting)大神你好,帮忙看下这个报错是哪里版本不对了吗?
      An unknown server-side error occurred while processing the command. Original error: Unsupported locator strategy: -ios predicate string请问如何设置隐式等待呢? 我使用了 implicitly_wait 但是实际执行的时候好像并没有效果

    匿名

    发表评论

    匿名网友
    确定

    拖动滑块以完成验证