如何确保API 的稳定性与正确性?你只需要这一招

** 在iOS上比Xpath更好的找元素方法**

Appium有多种元素定位方式,大部分借鉴了Selenium,下面总结了常用的定位方式,并标注出在iOS driver(XCUITest
driver)上是否可用:

可以看到,iOS有7个定位方式,注意没?XPath也在其中,对于XPath,有人欢喜有人愁!

** Xpath**

xpath的一个优点是使用层级定位策略,能够找到DOM(多用于Selenium)和app(多用于apppium)上的各种元素。如果app上的某个元素没有任何属性,用XPath可以方便的找到://[1]/[1]/[3]/[2]/[1]/[1]。

但这个方法不好,如果app的结构有变,方法就会失效。其实app层级结构非常不稳定,每次运行(比如淘宝的推荐每次打开都不同)或者升级app版本(比如添加一个新组件或者改变底层UI库)都可能引发层级改变。

如果你使用 XCUITest
driver,更是雪上加霜,因为XPath会非常慢。XPath和XML不是iOS的原生语言,每次运行XPath查询语句,都会把app层级结构转换成XML。这将花费大量的时间!然后,XPath将在XML上工作,找到想要的元素后,需要把元素再转换成真实元素,最后传回客户端,

XPath太厚重了,你可以使用属性定位(//XCUIElementTypeButton[@name="Foo"])解决层级问题,但转换成XML无法避免。怎么办?三个字:放弃Xapth!

最好的方法是使用id, name, 或者 accessibility id定位。如果你山穷水尽,又不想使用XPath,不妨看看今天的主角:Predicate
String定位和class chain定位。

** iOS Predicate String定位**

苹果开发出Predicate string,它支持基本的比较和匹配。只需给一个简单条件就能完成匹配。XCUITest driver使用predicate
string能匹配多个元素属性:name、value、label、type、visible...

下面的例子取自WebDriverAgent predicate string guide:

type == 'XCUIElementTypeButton' AND value BEGINSWITH[c] 'bla' AND visible == 1

这个predicate字符串匹配以'bla'开头的可见按钮,可以把它改写到appium上(java),需要用到 MobileBy方法:

String selector = "type == 'XCUIElementTypeButton' AND value BEGINSWITH[c] 'bla' AND visible == 1";driver.findElement(MobileBy.iOSNsPredicateString(selector));

predicate优点:

https://developer.apple.com/documentation/xctest/xcuielementquery/1500768-element

WebDriverAgent predicate string guide:

https://github.com/facebookarchive/WebDriverAgent/wiki/Predicate-Queries-
Construction-Rules

官方对predicate string的介绍:
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html

** iOS Class Chain 方法**

class chain定位方法是predicate
string和XPath的混合,由Appium自己开发,提高了层级查找的速度。它不如XPath万能,但性能非常好!class
chain把查询语法映射到XCUITest上,不建立UI树结构。它的语法比较像XPath:

  • XCUIElementTypeWindow[2] 选择第二个window。

  • XCUIElementTypeWindow[label BEGINSWITH "foo"][-1] 选择label属性以foo开头的最后一个window。

  • **/XCUIElementTypeCell[name BEGINSWITH "C"]/XCUIElementTypeButton[10] 选择以C开头的第一个cell,找到它的的第十个XCUIElementTypeButton子元素。

在java中,需要这么调用: java

driver.findElement(MobileBy.iOSClassChain(selector));

从这个例子可以看出, class chain定位是一个非常强大的搜索过滤器。如果使用XPath太慢,不妨试试它!

需要注意,这些定位方式也有一些缺点,比如不跨平台,再比如你必须知道iOS元素属性的predicate strings。

来霍格沃兹测试开发学社,学习更多软件测试与测试开发的进阶技术,知识点涵盖web自动化测试 app自动化测试、接口自动化测试、测试框架、性能测试、安全测试、持续集成/持续交付/DevOps,测试左移、测试右移、精准测试、测试平台开发、测试管理等内容,课程技术涵盖bash、pytest、junit、selenium、appium、postman、requests、httprunner、jmeter、jenkins、docker、k8s、elk、sonarqube、jacoco、jvm-sandbox等相关技术,全面提升测试开发工程师的技术实力
QQ交流群:484590337
公众号 TestingStudio
点击获取更多信息

上一篇:oracle 中的Ipad()函数


下一篇:Java8 函数式接口 @FunctionalInterface以及常用Consumer、Supplier、Function、Predica