Appium对于xpath 查找元素慢的原因

http://appium.io/slate/en/master/?java#ios-predicate

https://developer.apple.com/library/ios/documentation/DeveloperTools/Reference/UIAutomationRef/


xpath 需要遍历整个元素树,生成一个 xml 数据,然后再做 xpath 查找。遍历和在 xml 中进行 xpath 查找都相当耗时。
除 xpath 外主要有几类方法。
UIAutomation 代码(如 ios-predicate),直接执行,速度杠杠的。
byId,byName,byAccessibility 这些都是边查找边比较,不会遍历所有元素,所以速度相对快。
至于前面 @among29 提到的 page_source 的坑,不知和我们遇到的是否一样?我们遇到的是用例不稳定,is_display 方法和 click 方法有一定概率失效,结果发现失效原因是 appium 在 find 的时候缓存的对象已经失效(我们项目中是对应的 app 元素已经被 remove+add 过,内存地址都已经改了),但调用这个对象的方法也不会出错(没有任何异常抛出,只是一直 click 会报错,而 is_display 一直返回 False )。标志是获取这个元素的坐标(el.position)出来的值很不正常,会有一个带有 e32 的无穷大值。

现在我们通过改造 appium 对应模块的方法解决,主要改了两处:

在内部缓存中不仅存储元素对象,还存储元素查找方法。一旦对象无效(如 name 属性为 null)就执行查找方法再次查找,如果找不到(UIAElementNil),就抛 StaleElementReference 异常。对应代码:https://github.com/appium/appium-uiauto/compare/master...chenhengjie123:element-cache-fix
增加一个 onlyVisible 属性,在 xpath 查找和 byId,byName 查找中跳过不可见元素(ByUIAutomation 暂时还没做,还在构想要怎么做中),一个是提高查找效率(遍历的元素数量少了),另一个是更好地实现 android 和 iOS 脚本复用(iOS 上有些隐藏元素和可见元素有一样的 id 和 name )。对应代码(还在调试中):https://github.com/appium/appium-uiauto/compare/master...chenhengjie123:hide-invisible-elements
由于修改的不是 appium 核心代码,所以只需要用这个修改后的替代原来的 appium-uiauto 就可以了。
关于 Appium IOS 测试速度优化策略
1.尽量避免使用xpath: -
xpath的通用灵活性使用起来确实很方便,一开始我们找元素是全部用二次封装的xpath来查找;然而对比后却发现,用xpath找元素要比ByName和其他慢很多。所以建议大家尽量避免使用xpath查找元素。
2.用SetValue代替SendKey: -
//C#语言:
AppiumWebElement appiumElement = (AppiumWebElement)driver.FindElementById("账号");
appiumElement.SetImmediateValue(“136xxxx9501”);
代替:

IWebElement element = driver.FindElementById("账号");
element.SendKeys("136xxxx9501");
3.尽可能少的去和appium通讯: - 能直接在代码中处理的,就尽量在代码中处理,减少和appium的通讯,例如:
startX = elmentA.Location.X ;
endX = startX /5 ;
代替:

startX = elmentA.Location.X ;
endX = elmentA.Location.X/5 ;
4.待尝试: - 另外想到的一种优化方式就是缓存页面,暂时还没开始做:思路是先用driver.PageSouce将页面缓存起来,重写查找方法,先去缓存中找元素,缓存中找不到时,再重新用driver.PageSouce下载页面元素重新找。这种方式理论上会快很多,不过麻烦的是需要重写很多东西了。

你可能感兴趣的:(Appium)