前言

最近在做IOS自动化测试,IOS的Appium环境都配置OK,Demo脚本运行没有问题,多开执行没有问题,IOS安卓统一平台调度集成没有问题,可以进行自动化测试。
课时真正执行用例时发现个严重问题:执行速度过慢,慢的像中国男足,Appium的执行log满屏刷,找元素像男国足球场一样骚,一个像无头苍蝇满场跑,一个有模有样的一轮又一轮的查找,就是命中不了。
很是蛋疼,一直疼了好几天,都有放弃的念头了。

调查

Xcode9 SDK不再支持snapshot功能了,没有snapshot功能就无法获取page_source。而从Appium1.6.5+后,Facebook用WDA snapshot, 相比于Xcode SDK的snapshot, WDA snapshot在生成page source的时候包含了一个之前没有的属性, 也就是visibility属性。计算元素的visibility在XCTest中是非常痛苦和昂贵的操作。
xpath 好像每次查找时都是重新生成一棵树,WDA需要额外的努力来实施XPath查询,这会严重影响查找时间遍历整个元素树,生成一个 xml 数据,然后再做 xpath 查找。遍历和在 xml 中进行 xpath 查找都相当耗时。论坛比较多的说法是查找元素策略的性能从高到低排列如下:Class Name>Accessibility Id>Link Text>Predicate>Class Chain>XPath
但是以上各种方式试过了,也没有让我的用例快起来。

大坑

搜索了很多帖子,很多人都是反映IOS自动化速度太慢。但是都没提怎么解决。由于不想改现在共通的滑动和安卓手机按键操作的代码,没有java-client升级,保留当前5.0.4的版本,没有想到掉这么个大坑里,搞了两三天百撕不得骑姐。
和py最新库执行相同用例后的速度对比后才发现,可能是jar包的原因。升级java-client版本5.0.4-->6.1.0,升级前来执行6分钟左右的下单用例,升级后2分钟(包括人为设置的等待时间)不到就执行完成了。
更换版本后真的快的飞起啊,比安卓用例执行更快了。
这里说一下我的环境配置,方便速度慢的同学参考:

  • Xcode:9.4.1
  • Appium:1.8.1
  • 模拟器:11.4
  • java-client:6.1.0(非常重要,和5比速度差的不是一个级别的)

元素定位优化策略

  • 尽量不使用xpath

长的Xpath定位可以使用谓词定位,Accessibility Id定位等来逐步缩小搜索的范围,曲线救国。如下例:

IOSElement inputEL = driver.findElementByXpath("//XCUIElementTypeNavigationBar[@name='LVMMTabBar']/XCUIElementTypeStaticTex");

转换成

IOSElement  barEL = driver.findElementByIosNsPredicate("type == 'XCUIElementTypeNavigationBar' AND name == 'LVMMTabBar'");
IOSElement inputEL =barEL.findElementByIosNsPredicate("type == 'XCUIElementTypeStaticText'");

但是由于有些复杂的Xpath很难完全将Xpath的定位方式转换成Class Name,Accessibility Id,Predicate或者classChain定位,所以Xpath还是不能抛弃的。
只能说尽量不使用xpath特别是页面元素比较多的时候。不到万不得已,尽量不用(页面元素少,速度还可以接受时,可以不转换,灵活运用,转换前后性能自行比较一下)。

  • 尽量使用高性能查找

各种查找元素策略的性能从高到低排列如下(未一一按时间来具体验证):
Class Name
AccessibilityId
Link Text
Predicate
classChain
XPath

使用方法这里就不一一赘述了。很多同学估计对谓词不了解,也是java-client版本5.0.4以及以后版本才可以使用的,用下来感觉蛮好的的。
可以看一下全网最好的谓词扫盲贴---->谓词大法传送门

  • 尽量使用精确查找

例如通常我们知道"name='https://testerhome.com'"的元素只有一个时,尽量使用

IOSElement  niubiEl = driver.findElementByIosNsPredicate("type == '最牛逼的测试交流论坛' AND name == 'https://testerhome.com'");

不要使用

List<IOSElement> niubiEls  = driver.findElementsByIosNsPredicate("type == '最牛逼的测试交流论坛' AND name == 'https://testerhome.com'");
IOSElement niubiEl = niubiEls.get(0);

同类的findElementByAccessibilityId和findElementsByAccessibilityId等

通常情况下findElements方法会遍历这个页面去找出所有匹配查询的页面元素,而findElement花费更多的时间, 因为findElement不会,而是仅仅返回第一个匹配查询的元素(机器是不会喊累,但也请不要让人家干无用功)。

  • 尽量少通配符

很多人喜欢封装,但是过度封装,使用很多通配符,以达到万能找元素的效果,但是可能带来的后果就是执行效率低。例如:

List<IOSElement>  comnEls  = driver.findElement("//*[contains(@name,'" + targetParam+ "') or contains(@label,'" + targetParam+ "') or contains(@value,'" + targetParam+ "')]");

调用是简单了,只需传个参数targetParam就好了,但是这需要扫描每个UI元素的所有name,lable,value属性(上面属性还可以继续加,达到万能匹配), 无疑这是极度低效的。
对于爬虫来说,可能需要爬取更多相关的东西,但是我们自动化来说,目标很明确。老老实实的的使用

IOSElement  niubiEl = driver.findElementByAccessibilityId("type == '最牛逼的测试交流论坛' AND name == 'https://testerhome.com'");

更高效。

  • 尽量减少和服务的通信

    if (driver.isElementExist("//XCUIElementTypeButton[@name='未选择']"))
    { driver.findElement("//XCUIElementTypeButton[@name='未选择']").click();
    }

    上述如果存在时,则会查找两次(也许例子不恰当)。不如把逻辑放在自己代码里。

    IOSElement  selEl = driver.findElement("//XCUIElementTypeButton[@name='未选择']");
    if(selEl != null)
    {
    selEl .click();
    }

升级后的小问题

升级后一些方法无法正常使用或者过时了。
点击升级前

new TouchAction(driver).tap(x , y).perform();

点击升级后

new AndroidTouchAction(driver).tap(PointOption.point(x , y )).perform();
安卓和IOS分开了
new IOSTouchAction(driver).tap(PointOption.point(x , y )).perform();

滑动升级前

new TouchAction(driver).press(beginX, beginY).waitAction().moveTo(endX, endY).release().perform();

滑动升级后

new AndroidTouchAction(driver).press(PointOption.point(beginX, beginY)).waitAction().moveTo(PointOption.point(endX, endY)).release().perform();
安卓和IOS分开了
new IOSTouchAction(driver).press(PointOption.point(beginX, beginY)).waitAction().moveTo(PointOption.point(endX, endY)).release().perform();

Android按键操作
升级前

driver.pressKeyCode(AndroidKeyCode.HOME);
driver.pressKeyCode(AndroidKeyCode.BACK);
.
driver.pressKeyCode(AndroidKeyCode.KEYCODE_NUMPAD_9);

升级后

androidDriver.pressKey(new KeyEvent(AndroidKey.HOME));
androidDriver.pressKey(new KeyEvent(AndroidKey.BACK));
.
androidDriver.pressKey(new KeyEvent(AndroidKey.NUMPAD_9));

后记

升级版本后总于解决了执行龟速的问题,蛋也不疼了,如同梦中看到国足秒杀欧冠一样的快意,看着执行速度快的飞起,简直要GC了。
这些遇到的一些小坑,总结分享一下。大神轻喷,分享给那些和我一样low 的人(看到很多人Q群里问环境搭建,Demo跑不了,求视频,还有很多付费培训广告),我感觉分享还是很有必要的,毕竟大神麼就你们几个。

关于IOS执行速度,你有什么骚操作,欢迎一起交流探讨。

一招让 IOS 自动化化快的飞起的更多相关文章

  1. iOS自动化环境搭建——macaca

    macaca-java for ios 自动化环境搭建 基础原理解析:https://testerhome.com/topics/6608 一.环境搭建 1.安装eclipse; -----Java开 ...

  2. 初识ios自动化(一)

    Appium进行自动化测试有两个好处: 1. Appium在不同平台中使用了标准的自动化APIs,所以在跨平台时,不需要重新编译或者修改自己的应用. 2. Appium支持Selenium WebDr ...

  3. iOS 组件化

    iOS 组件化介绍 随着应用需求逐步迭代,应用的代码体积将会越来越大,为了更好的管理应用工程,我们开始借助CocoaPods版本管理工具对原有应用工程进行拆分.但是仅仅完成代码拆分还不足以解决业务之间 ...

  4. 基于facebook-wda的iOS自动化操作实践记录

    [本文出自天外归云的博客园] 原理 对于iOS自动化操作,主要靠WebDriverAgent来完成.在Mac电脑上连接真机iPhone,运行WebDriverAgentRunner会在Mac端启动WD ...

  5. Jenkins+ Xcode+ 蒲公英 实现IOS自动化打包和分发

    Jenkins+ Xcode+ 蒲公英 实现IOS自动化打包和分发 直接入正题: Screen Shot 2015-09-18 at 16.56.20.png Mac上安装Jekins jekins下 ...

  6. 使用CocoaPods创建自己的私有库-iOS组件化第一步

    目前iOS组件化常用的解决方案是Pod+路由+持续集成,通常架构设计完成后第一步就是将原来工程里的模块按照架构图分解为一个个独立的pod工程(组件),今天我们就来看看如何创建一个Pod私有库. 新建: ...

  7. iOS 组件化路由框架 WisdomRouterKit 的应用

    [前言] 大家好,写作是为了和读者沟通交流,欢迎各位开发者一起了解 WisdomRouterKit SDK 的功能. 关于 iOS 组件化路由方案框架: WisdomRouterKit 的功能介绍,之 ...

  8. iOS组件化实现方案

    作者原文iOS组件化 - 路由架构从0到1实战  合伙呀 1.CTMediator作为路由中间件 2.基础UI组件以pod形式引入,并且能够独立运行调试 3.基础工具组件以pod形式引入,并且能够独立 ...

  9. IOS自动化打包介绍

    IOS自动化打包介绍  标签: app打包 , Ios打包 , iphone打包 , iphone自动化打渠道包    分类:无线客户端技术, 贴吧技术 摘要 随着苹果手持设备用户的不断增加,ios应 ...

随机推荐

  1. vue项目结构搭建

    1安装node.js,已集成npm 2.临时使用淘宝镜像 npm --registry https://registry.npm.taobao.org install express 3.instal ...

  2. PDO查询语句结果中文乱码

    PDO::MYSQL_ATTR_INIT_COMMAND (整数)连接到MySQL服务器时执行的命令.重新连接时会自动重新执行.请注意,此常量只能driver_options 在构建新的数据库句柄时在 ...

  3. rancher2.1.7安装nfs 存储类

    NFS存储类不建议作大规模存储,块存储建议采用CEPH(独立安装) NFS只作为外接存储与普通NGINX类的配置文件,业务配置文件建议走配置中心. 增加自定义商店 地址为:https://github ...

  4. appium 移动端自动化测试一

    最近公司决定使用appium为主体框架做一个移动端得自动化测试系统,我会陆续记录项目得进展. 1.首先是appium环境得搭建, 需要安装appium-server ,appium-desktop, ...

  5. 19-05【icloud】照片备份

    icloud提供了免费的存储空间,5G,超过这个量需要单独购买空间:我用的是50G,每月6元. 如果在mac或者iphone上开启了本地的照片流,则会自动同步到icloud,同时各个设备的客户端(ip ...

  6. Find out where to contain the smartforms

    Go to table E071 and give smarforms name and it will give the transport req for that. Run SE03, choo ...

  7. vue学习笔记(nvm安装)

    https://github.com/creationix/nvm https://github.com/coreybutler/nvm-windows 慕课网:https://www.imooc.c ...

  8. 监控服务器配置(四)-----OracleDb_exporter安装配置

    1.下载oracle客户端安装包(linux版)到 /opt/minitor/oracleDb . 下载地址:https://download.csdn.net/download/a155657721 ...

  9. thinkphp 响应对象

    <?php namespace app\admin\controller; use think\Request; class Index{ public function index(Reque ...

  10. Qt5.12.2开发Android环境搭建

    Qt-Android开发环境概要qt-opensource-windows-x86-5.12.2----armv7jdk-8u201-windows-x64android-ndk-r18b-windo ...