您现在的位置: 首页 > 微信营销 > 营销推广 > 携程app下载,

携程app下载,

作者:   来源:  热度:3  时间:2021-01-14







作者简介 天超,携程资深软件工程师,关注iOS研发,喜欢用脚本语言解决各种难题。引言开发效率的提升,是开发者关注的一个永恒的话题。对于iOS而言,编译速度一直是影响iOS开

作者简介

 

天超,携程资深软件工程师,关注iOS研发,喜欢用脚本语言解决各种难题。


引言

开发效率的提升,是开发者关注的一个永恒的话题。对于iOS而言,编译速度一直是影响iOS开发和集成测试效率关键的一环。携程旅行App iOS工程编译,经历了从全源码编译到工程组件化,细分Bundle,再到细分Bundle基础上的进一步优化四个阶段。每次的优化改造都是不断结合业务反馈,深入了解xcode编译过程后的成果。

一、背景

简单回顾一下在做Bundle拆分之前的情况,当时整个iOS工程的所有代码都在一起,并未做工程拆分和解耦,编译时全都是源码编译,数百万行代码全部编译完成要将近一个小时。所有的开发人员都在一个工程里开发,如果因为某个人提交的代码有问题(这是常常会发生的),导致编译了很长时间之后才报错,更是耽误时间,严重影响开发效率。对于测试人员来说,每次需要验证一个功能时打包测试都需要至少等待几十分钟,这是极大的资源浪费。这个时候的Build过程是全源码complie,几千上万个文件都需要编译、链接,效率可想而知。所以为了提高开发和测试的效率,提高iOS工程的编译速度刻不容缓。

二、优化方案

2.1 工程组件化

第一个优化是把整个工程的编译过程打散,把代码按照业务线拆分成一个个独立的子工程,每个子工程的编译过程都是独立的。每个子工程只需要保证自己工程的源码能够编译成功,对外输出统一的静态库和资源文件包的产物。这个产物我们叫做Bundle。单个业务工程(Bundle):App Build:对于单个业务来说,编译时间大大缩短,整个Build过程变成单工程complie,多工程link,极大减少了Build过程中的complie花费的时间。这样有两个好处:1)对于开发人员,每个业务开发只需要把自己这个子工程切为源码引用,把其他非自己模块的子工程全部用静态库依赖,本地编译也只需要编译自己的子工程,可以大大提升本地开发编译速度。2)对于测试人员,打包过程就变成了把所有已经编译好的子Bundle静态库链接到一个壳工程里,不需要对每个文件进行编译,可以很快的打包测试验证。

2.2 增量编译

在工程组件化之后,在持续集成平台上单个Bundle的打包时间还是过长。因此框架团队开始研究单个Bundle在持续集成平台上增量编译的可能性。经过调研,最终选定CCache做为解决方案。CCache是一个编译工具,可以将Xcode编译文件缓存起来,从而达到编译提速。针对本地开发该方案具有优势,但是在结合自研的移动发布平台MCD(Mobile Continuous Delivery)(后面简称【发布平台】)上使用时效果并没有达到预期,主要有两点原因:1)同一Bundle多分支共存 :App会存在大小版本同时开发的情况,在发布平台中也就会存在不同版本、不同分支的情况。2)缓存管理不便 :发布平台打包机器通常仅有250G磁盘空间,当面临磁盘压力时,需要灵活的清理策略。最终框架团队采用了自管理,能做到缓存物理隔离,同时也就省去了环境配置的步骤。增量编译具体实现:1)合并有变动的文件
  • 打包任务会根据新的 commitId 下载一份代码副本,不能直接使用该副本,因为代码文件内容没有变动,仅仅是文件属性的变动也会导致 xcodebuild 缓存不生效。因此需要副本和工作区内的源码做diff,仅仅合并内容有变动的文件。
  • 使用 python 的 filecmp 实现合并代码逻辑,并且支持配置 ignore。
  • xcodebuild 指定 -derivedDataPath 设置缓存路径,并将该目录配置到 diff ignore中。
2)提供清除缓存的功能
  • xcodebuild的缓存有时候会出问题,比如修改了c++文件后有时并不会生效,这种需要提供清除缓存的功能,可以由开发自由选择使用。
截止到以上两步,Native已经基本实现了增量编译,但是实际使用还不够。因为打包主要是在集成系统平台上面完成的,集成平台打包有多台机器。携程旅行App的打包Jenkins采用的是master-slave模式,一个Job下会有多个节点,Job是随机抽取的节点。为了提高增量编译的命中率,必须要让Bundle和节点关联起来。比如:有ABCD四个节点,HotelBundle每次都落到A节点,这样才能保证A节点中HotelBundle的xcodebuild缓存有效,并且代码diff差异最小。具体实现:1)保留Jenkins Job的工作区该步骤是在Jenkins Job的配置中操作,取消勾选下图中的Delete workspace before build starts

2)使用Jenkins插件建立Bundle和节点的关联基于Jenkins Label Parameter Plugin,并做改造,实现伪随机,以保证关联的节点下线之后,能使用候补节点正常工作。发布平台前端提供关联配置,业务可以按需选择使用。

通过以上步骤就实现了增量编译,但是该方案针对swift不生效。swift在Release模式采用的全量编译(如下图),做整体优化。不过swift Bundle可以采用上述Bundle拆分的方案。

以某一个编译源码文件197个、资源文件142个的Bundle为例看下效果。

采用增量编译后,Bundle编译耗时由116s降为9s。

2.3 Bundle细分

最初携程旅行App的Bundle都是按照业务来拆分的,比如:酒店就一个Hotel Bundle,在当时编译速度已经不慢了。但是随着业务的发展,单个Bundle中业务代码越来越多,文件越来越多,导致编译又会变慢。这时,可以将单个Bundle按照功能做更细粒度的拆分,比如酒店拆分出了酒店主工程、酒店基础工程。更细粒度的Bundle拆分还能带来以下其他收益:
  • 加快本地开发编译:某个功能的开发人员只需要将自己这个功能模块切为源码,其他模块全用静态库,提高本地开发编译效率。
  • 为其他独立app提供更细粒度的模块功能支持:我厂的很多独立App都是共用一套框架和基础组件的,按功能模块细粒度的拆分出独立的模块Bundle后,可以使独立app在选择基础组件时按需选择。

2.4 合理设置头文件搜索路径

业务工程往往会大量依赖基础库代码,在本工程编译过程中,也需要查找到引用的基础代码的头文件。因为代码还是在同一个仓库里,之前的方案是头文件搜索设置还是指向本地的基础框架代码,使用循环搜索的方式。这样的好处是任何一个头文件的修改,使用方可以马上感知到。缺点就是头文件没有特意为方便调用进行组织,搜索起来特别费时。经过统计,Hotel一个文件的编译往往都是秒级别。一整个工程编译下来就是十几分钟。因此框架团队意识到必须要和第三方库一样,在目前的.a和资源文件之外,提交include目录包含所有会被外部使用的头文件。同时,考虑到iOS开发向Swift转型的需要,如果在include目录的基础上,还能够提供一份基于include里头文件的module.mapmodule文件。将方便后期业务方向Swift的迁移。具体方法是:1)首先框架的Bundle,在工程设置中点击工程的Target→Build Phases→Copy Files点击+,输入.h把需要暴露的头文件都添加上。这样会在输出产物的Build目录下,多一个include目录,再通过脚本去把这个目录里面的所有文件复制出来,同时生成module.mapmodule。2)使用的时候,将头文件搜索路径设置到include目录,并且设置为非递归搜索。

2.5 建立中央缓存

费雷德里克·布鲁克斯说软件工程领域没有银弹。通过以上优化后,减少了编译时间,提升了开发和集成测试的效率,但这也不是解决编译速度问题的银弹。随着业务的不断使用,又出现了新的问题:Bundle拉取时间过长。Bundle化方案各个业务的静态库生成都是在发布平台上编译的,业务在本地开发的时候再使用框架的脚本拉取bundle到本地。发布平台上打测试包的时候也是需要拉取所有Bundle。发布平台打包过程如下:1)初始化Jenkins工作区,下载代码副本2)下载Bundle3)使用xcodebuild生成ipa4)上传ipa和符号表5)Job状态回调整个过程共耗时7分钟,目前携程旅行App iOS最新的版本的上线Bundle将近70个,每个Bundle的静态库支持arm64、x84_64等指令集,所有Bundle加起来有4G大小,即使在内网全量下载耗时也要2~3分钟。比如酒店某一Bundle:

所有Bundle全量更新一次耗时:

针对这个问题,解决方案是建立中央缓存。在用户根目录下,建立一个隐藏的目录.iOSBundleRepo,按照Bundle的版本号存储,同一Bundle可存在多个版本。工具下载Bundle时优先判断缓存,未命中时才开始下载并且缓存到repo中。建立中央缓存还能带来其他好处:在发布平台做预缓存,使用定时任务更新中央缓存,进一步节省下载耗时。该方案实际上采用的是空间换时间的策略,随着时间推移,将会带来磁盘不足的问题,所以必须要实现清理机制。针对不同使用场景需要采用不同的缓存清理策略,具体如下:
  • 本地开发:该模式下,开发可以自由选择更新最新Bundle和仅更新配置,缓存使用不频繁。所以将同一Bundle版本个数调低,缓存有效期拉长。
  • 持续集成:发布平台打包较为频繁,缓存使用比较频繁,并且Bundle版本变动较快,所以将同一Bundle个数调高,缓存过期时间设置为一天。
最终,打包耗时由原来的7分钟降为5分钟。

三、存在的问题和思考

软件开发工程没有银弹,大家都是在焦油坑里挣扎。Bundle的方案节省了编译的时间,提高了开发的效率,方便了持续集成和测试。为了提高单Bundle编译速度而导出头文件的方案,牺牲了一定的灵活性换来了编译速度的提高。头文件没有了代码中的直接搜索,框架开发人员从共同开发者真正变成了库提供者,这就要求每一次都接口的修改都要及时更新并导出。任何一个技术方案肯定是在权衡各方面之后做出取舍的结果。框架团队为了提高iOS Build速度,通过自研的方案,做了拆分Bundle,优化头文件搜索路径,增量编译,建立中央缓存等步骤,基本上满足了现有我厂各业务线的日常开发需求。

【推荐阅读】

“携程技术”公众号后台回复“新书”

免费获得两本书的试读样章~

《携程架构实践》

京东

当当

《携程人工智能实践》

京东

当当

 “携程技术”公众号

  分享,交流,成长

 作者简介

 

Felix,携程高级测试经理,关注无线测试、DevOps、测试框架方面的技术和动态。


从自动化测试诞生以来,始终阻碍其成功落地实施的重要因素之一是频繁变更的业务需求,导致自动化测试维护成本极其高昂。尤其是随着近些年敏捷开发,DevOps开发模式的流行,一方面迫切地希望在开发生命周期内提高自动化测试的占比,从而缩短测试时间,增加开发迭代次数来加快开发进度和保证开发质量。而另一方面,随着迭代开发频率加快,需求的频繁变更却进一步加剧了维护自动化测试稳定性的难度。这两者不可调和的矛盾往往导致了自动化测试实施的难以为继,很多时候自动化测试成为了鸡肋,食之无味,弃之可惜。

那么如何减少需求变更对UI自动化测试的影响,如何另辟蹊径顺利地进行UI自动化测试?本文后续一一为你解答。

一、自动化测试不是银弹

 “自动化测试不是银弹” 这个观点已经得到业界的普遍认同,那么为何业界还是如此推崇自动化测试呢?测试完全的自动化固然不太可能,但在合适场景使用合理的自动化测试,却依然可以发挥出巨大的作用,得到较高的收益。

对于UI自动化测试而言,业务频繁变更导致的UI变化是UI自动化测试失败的主要原因。如果我们能尽可能地消除UI变化对自动化测试的影响,则势必会极大地提高自动化测试的稳定性。

梳理下一条UI自动化测试用例的结构,我们可以简单地归纳出如下图所示的关系:

 

自动化测试用例结构简化图

 

UI界面中控件的变化无疑是很频繁的,给自动化测试的实施带来很大的障碍。如果能切断业务操作和结果断言对于控件的依赖,则可以很大程度地提高自动化测试的稳定性。而随着图像识别技术的进步,通过图像识别技术摆脱对控件的依赖正逐渐成为可能。

二、视觉测试

  

UI自动化测试在验证预期结果是否正确时,通常是通过验证预期结果某些关键信息来实现的,比如是否出现某个关键字,是否标题正确等等。这种验证方式固然简单,却也存在不少的不足,其中最大的不足就是无法验证UI的样式。

UI是最终呈现在用户面前直观的东西,UI交互和样式的好坏直接决定了用户对一款产品的直观印象。视觉测试是验证UI是否正确展示给用户的测试手段之一,通过视觉测试可以找出产品在可视化中存在哪些缺陷,比如字体,布局等问题。那么如何实施视觉测试呢,业界最普遍的做法就是图像比对,具体实施步骤网上相关的资料不少,这里就不赘述了。

三、Watcher

Watcher是一个基于图像比对的App和Web视觉测试平台, 主要分为三个部分:SDK,图像比对服务,Watcher比对平台。

Watcher SDK主要用于与自动化测试框架(如Selenium,Appnium , Airtest)结合来实现与Watcher比对平台的交互(比如图片上传,客户端信息收集,验证结果返回等等)。Watcher比对平台则主要进行图像管理,测试配置管理,测试结果查看,人工确认等工作。图像比对服务则提供了图像比对,AI识别等服务。

Watcher部署架构图

 

Watcher作为视觉测试平台,其实现原理也遵循视觉测试的基本步骤,大致可以分为以下几个步骤:

1)在UI自动化测试框架引入Watcher SDK,编写测试用例并在测试用例合适的位置调用Watcher的Check方法进行图像比对;

2)Watcher平台在接收到截图后,会首先进行判断是否有对应的基线图,如果有基线图,则会与基线图像进行比对;如果没有基线图,则会将此次截图自动作为基线图。

3)查看图像比对的结果

a. 如果比对差异是由功能变更引起的,则审查通过并以最新截图作为新基准图;

b. 如果比对差异确定是缺陷,则记录缺陷,基准图保持不变;

视觉测试流程示意图

3.1 Watcher SDK

进行视觉测试的第一步就是收集被测系统的信息和截图。为此,我们编写了支持目前主流自动化测试框架的SDK,分别为Appnium SDK,Airtest SDK,Selenium SDK。

Wathcer SDK的主要作用包括:

  • 收集被测系统的环境信息(分辨率,机器信息等)

  • 定义用例信息

  • 截屏并上传到服务器进行比对

使用Watcher SDK非常的简单,将SDK引入到自己的自动化项目后,在测试用例中编写如下语句就可以使用,实现无缝接入。

watcher = Watcher_util()watcher.watcher_open("测试用例名称")watcher.watcher_check("验证点1")....测试代码watcher.watcher_check("验证点2")

Airtest SDK编写测试用例代码示例

3.2 Watcher图像比对服务

  

图像比对服务是一个RESTFUL的服务站点,对外提供了一系列的服务用于进行图像对比,并返回对比结果。该服务是一个微服务的站点,如果图片比对压力较大,可以通过横向扩展的方式来扩展图像对比的服务能力。

3.3 Watcher比对平台

Watcher比对平台是一个Web站点,主要负责图像比对,比对测试结果展示,测试配置等工作。在Watcher比对平台中,我们可以很直观的查看比对的最终结果,测试用例的简短信息,并对成功/失败/新增的用例用颜色和图标加以区分。

比对平台结果列表页

 

对于对比失败的测试用例,仍然需要测试或开发人员进行人工审查确认,相关人员可以在比较结果详情页中查看对比的详细结果。如果测试用例实际为通过,则将结果标记为通过,如需替换基准图,则亦可以选择将最新截图替换为基准图。如果测试结果实际为失败,则将结果标记为失败并记录缺陷。

 

对比结果详情页

 

在对测试结果进行审查的过程中,也可以对测试用例的对比设置进行修改,比如设置忽略区域,设置阈值等。

四、实时比对

传统的图像比对测试是最新的截图与基线图进行比对,通过与基线图的差异来识别是否存在缺陷,我们称之为基线比对。通过实践,我们发现在有些场景下,基线比对的效果并不理想,比如查询结果页。该页面具有较强的时效性,也许时隔一天,查询的结果就截然不同,自然就对比对的结果造成了很大的干扰。所以我们在Watcher中加入了实时比对。

实时比对跟基线比对并没有本质的区别,区别只在于跟谁比的问题。开启实时比对后,我们可以在新旧版本上同时执行自动化用例,Watcher会将收集到的截图进行比对,从而消除时效性带来的干扰,提高比对的准确性。

基线比对和实时比对示意图

 

五、图像比对算法

   

视觉测试的关键在于图像比对,那么图像比对算法的优劣就成为了视觉测试是否成功的关键所在。Watcher提供了多种图像对比的模式,分别为精准比对(像素),内容比对以及AI比对。

  
5.1 精准比对

 

精准比对是通过像素比对来实现的,也是Watcher默认和最常用的比对方式。这里我们使用OpenCV中的算法来实现。大致算法流程如下:

 

精准比对的算法流程

 

5.2 模板比对

  

模板比对是先在基线截图中圈出需要比对的区域截图,然后在最新截图中根据该区域截图进行图像模板匹配的一种对比方式,也是通过OpenCV的算法实现。

模板比对算法流程图

5.3 内容比对

  

精确比对的优势在于比较全面,页面的样式,内容都在比较范围之内,但有时过于灵敏,稍微有些样式的变动就会影响比对的结果。所以对于有些页面或区域,也可以选择内容比对的方式。内容比对主要通过图像的文字识别实现。

 

内容比对算法流程图

 

5.4 AI比对

  

AI比对是Watcher中的一种尚在探索试用阶段的比对方式,通过AI图像识别技术,我们即可以智能的忽略正常差异的部分(比如日期,控件大小变化等),也可以识别出存在异常的部分(比如图像缺失,文字堆叠等),使用YOLOv3实现。

AI比对算法流程以及部分识别的效果

 

六、结束语

  

在本文中,我们介绍了Watcher如何结合UI自动化测试框架实现视觉测试以及在实施视觉测试过程中的一些实践所得。Watcher提供了从SDK,图像对比,结果展示到人工确认的一整套的功能和视觉测试解决方案。目前在团队使用过程中得到了积极的反馈:

  • UI自动化测试用例数量缩减50%以上,部分模块缩减80%;

  • UI自动化测试执行较之前更加稳定,执行时间缩短30%以上;

  • 提高测试人员排查和分析问题效率;

当然在使用过程中也发现了很多的不足,比如在有些场景下比对误报率偏高,不支持跨平台比对等,这些都是我们需要改进的地方。我们还会在AI比对中挖掘更多的适用场景,比如随着AI算法的优化,也可以将AI图像识别扩展到控件查找上,从而更便利的编写自动化测试用例。

【推荐阅读】

京东5折优惠+满减活动ing

《携程架构实践》

京东

当当

《携程人工智能实践》

京东

当当

 “携程技术”公众号

  分享,交流,成长

转载请注明出处:携程app下载,:http://www.720weixin.com/marketing/341322.html
  • 登录

    使用微信帐号直接登录,无需注册