作者:吕雨强

GrowingIO iOS 测试工程师,主要负责 iOS SDK 功能测试、自动化测试 。

GrowingIO 是基于用户行为数据的增长平台,精准采集用户行为数据是公司业务的基石,只有及时、准确、可靠的采集到数据,才能支撑上层的数据分析,用户画像,运营等业务,所以公司一直非常注重数据采集 SDK(Software Development Kit) 的质量保证工作。

为了满足客户的各种业务与技术的需求,GrowingIO 提供了 Web、Android、 iOS、Hybrid、各种小程序(微信、支付宝、头条、QQ 等 )、微信内嵌页等多种平台,以及 React Native、Flutter 、Cordova、Weex 、API Cloud 、AppCan 众多开发框架的 SDK,这无疑为 SDK 的测试工作带来的巨大的挑战。

本文主要介绍 GrowingIO 在 iOS SDK 测试方面的具体实践,希望对从事 iOS 测试的同学提供一些参考。

1. 数据采集 SDK 是如何工作的?

要测试一个软件或系统首先必须要先了解其业务逻辑和技术实现,接下来我们简单看下数据采集 SDK 是如何工作的。

GrowingIO 的数据采集 SDK 支持无埋点(全埋点)数据采集以及埋点数据采集,以满足不同的业务需求,其简易结构如下:

在用户打开 App ,浏览不同的页面,点击不同的元素(如按钮,文本框,图片),关闭 App 时,无埋点事件采集模块会将用户的具体行为自动采集并保存到手机的本地存储(关于无埋点数据采集的具体实现,欢迎关注 GrowigIO 后续的文章分享,这里不再详述)。

埋点事件采集与之类似,不同之处是埋点事件是由 App 主动调用 SDK 的埋点 API 触发事件采集,当然不同事件的具体数据格式有所不同。

接下来是数据发送模块,其主要负责将数据通过 HTTP API 上报到数据接收服务。

需要说明的是,为了节约用户的数据流量和电量,发送程序并不是实时上报的,它会根据设备的电量、网络类型、以及数据量进行发送时机的选择,而且发送前还会对数据进行压缩和混淆以降低传输数据量并提升数据安全性。

当然数据发送程序还会处理数据上报中的各种数据发送失败,网络异常等错误,采取适当的重试机制。

2. 如何测试?

通过以上结构分析,可以看出数据发送模块跟核心的数据采集业务关系不大,并且很稳定,几乎不会改动,因此我们测试的重点主要是数据采集部分,尤其是无埋点数据采集。

要测试数据采集首先需要有一个包含各种页面和元素的 Demo App,然后切换不同的页面,操作页面上的元素或触发埋点事件,然后检查采集到的事件数据是否正确。

检查事件数据有两种方式,一种是将事件详细数据通过日志打印出来观察日志检查;一种是通过抓包程序获取数据发送然后检查。

后者一般需要配置复杂的代理工具,而且数据量多,还需要考虑数据的解压缩、解密,比较难以精准定位到事件数据。所以在实际测试中一般使用前者。

上图是一个采集数据的日志截图,通过图中的事件数据我们发现,其字段众多,且一些字段可读性不高,人工检查耗时较长。

此外 SDK 数据采集的主要逻辑基本不变,但是每次修改都必须进行足够的回归覆盖,以免遗漏错误。

一旦遗漏了缺陷到线上,其造成的损失是极其昂贵的,即使在后续版本修复了缺陷,其造成的影响也很难消除,因为移动端 App 的升级周期是很难控制的。

在加上 GrowingIO 数据采集 SDK 兼容 iOS 8 及以上版本,需要对各个版本系统做兼容性测试,其测试工作量显而易见。

幸运的是 SDK 的业务变化很少,断言内容比较机械,特别适合自动化测试。而且回归测试工作量巨大,采用自动化测试可以极大的提升生产率和质量。

3. 选择测试框架

工欲善其事必先利其器,开展自动化测试之前必须选择一款合适的自动化测试框架。选择框架的时候有几个方面要考虑:

  • 开发的成本(支持语言,是否可调试,代码补全)
  • 维护成本(框架的稳定性)
  • 是否需要源代码
  • WebView 的支持(很多App都用到了H5)
  • 对操作系统,开发工具的支持情况( 是否支持 iOS 8)
  • 测试用例执行效率
  • 测试报告(截图,代码覆盖率,…)
  • 是否支持CI(持续集成)
  • ……

当前支持 iOS UI 自动化测试的主要框架对比如下:

考虑选择测试框架的几种影响因素。

首先,使用的语言和框架决定了测试人员的持续性学习成本,iOS SDK测试人员对 Objective-C 熟悉和掌握程度高,不需要消耗额外的学习成本,测试与开发同一技术栈。

其次,测试 App 程序根据需求时有调整,使用开发效率高、调试方便的测试框架能使我们在适应新 UI 变化、新需求时获得更小的投入产出比。

综合以上考虑,KIF 框架已经展现了他的优势,并且 KIF 使用 XCTest 框架,使得其测试流程 iOS 程序的单测无异,可完全复用单测的持续集成流程,维护持续集成的成本相对降低;另外,KIF 是一个活跃的开源测试框架,可扩展性好,升级更新快,有活跃社区来探讨和解决使用过程中遇到的问题。

鉴于上述优势,我们选择了 KIF 作为 iOS 的 UI 自动化测试框架。

KIF 的全称是 Keep it Functional,它是一个建立在 XCTest 的 UI 测试框架,通过 Accessibility 来定位具体的控件,再利用私有的 API 来操作UI。由于是建立在 XCTest 上的,所以你可以完美的借助 XCode 的测试相关工具。

4. 自动化测试的实施

语言与工具

  • 语言:Objective-C

  • IDE:Xcode

  • 测试框架:KIF

搭建测试环境

  • 在工程中添加Target实现,选择FileNewTarget… 菜单项,从中选择iOsTest中的UI Testing Bundle 模版,如下图所示:

  • 单击下一步,进入 Target 选项页面,设置测试工程相关项

  • Product Name: KIF 测试工程名,可以自由命名,最好是测试工程名 + “Tests”。

  • Organization Name,Organization Identifier,Bundle
    Identifier,根据需要自行命名即可。

  • Language: 编码语言,有 Objective-C 和 Swift , 根据需要选择,我们使用的是 OC。

  • Project 和 Target to be Tested:为对应的要测试的工程名,一定要保证是正确的。

  1. 完成 Target 设置后,点击 「Finish」按钮,创建成功。

  2. 安装 pod, 在命令行终端输入以下命令:

sudo gem install cocoapods
  1. 修改或创建工程的 pod 文件 Podfile
target 'GrowingIOTest' dopod 'SDCycleScrollView', '~> 1.75'pod 'MJRefresh'pod 'MBProgressHUD'
endtarget 'GIOAutoTests' dopod 'KIF','~> 3.5.1'

其中如下一段内容为新添加的

target 'GIOAutoTests' dopod 'KIF','~> 3.5.1'
end
  1. 在项目目录中执行以下安装命令, 安装相应的依赖,测试项目准备完成
pod install
  1. 准备好被测程序,在测试 Demo 项目中集成需要被测试版本的数据采集 SDK

编写测试用例

测试环境搭建完成后,接下来就是编写具体的测试用例了,一般测试用例的主要步骤为:

  1. 准备测试环境

  2. 执行测试步骤

  3. 测试结果断言

  4. 测试结果报告

  5. 清理测试环境

下面以 SDK 的无埋点元素点击事件自动化测试用例为例,说明自动化用例的编写。

测试用例:

启动 App,模拟用户滚动屏幕找到对话框按钮,然后点击对话框按钮,显示对话框后点击关闭按钮, 校验点击事件发送数据,发送内容正确。

代码实现:

- (void)setUp {// 一些初始化操作
}-(void)tearDown{// 一些结束动作
}-(void)testDialogBtnCheck{/**function:对话框按钮点击,检测点击事件,**/[[viewTester usingLabel:@"UI界面"] tap];//添加向下滚动操作[tester scrollViewWithAccessibilityLabel:@"CollectionView" byFractionOfSizeHorizontal:0.0f vertical:10.0f];[tester waitForTimeInterval:1];[[viewTester usingLabel:@"LabelAttribute"] tap];[[viewTester usingLabel:@"ShowAlert"] tap];[tester waitForTimeInterval:1];[[viewTester usingLabel:@"取消"] tap];[tester waitForTimeInterval:3];NSArray *clckEventArray = [MockEventQueue eventsFor:@"clck"];//是否发送clck事件 if(clckEventArray.count>=2){//判断点击事件是否字段发送正确NSDictionary *chevent=[clckEventArray objectAtIndex:clckEventArray.count-1];NSDictionary *clkchr=[NoburPoMeaProCheck ClckEventCheck:chevent];//NSLog(@"Check Result:%@",clkchr);XCTAssertEqual(clkchr[@"KeysCheck"][@"chres"], @"Passed");NSLog(@"对话框按钮点击,检测clck事件测试通过---Passed!");}else{NSLog(@"对话框按钮点击,检测clck事件测试不通过:%@!",clckEventArray);XCTAssertEqual(1, 0);}
}

由于我们主要测试 SDK 的功能,测试 Demo 是我们自己设计的,主要覆盖各种 UI 元素和事件,其业务逻辑比大多数的业务类型 App 都简单,没有什么特别介绍的。

这里介绍下断言的设计。前文介绍过,我们自动化测试的重点是数据采集规则正确,不关注数据存储与发送。SDK 在采集数据时会将所有事件先加入一个队列,然后再保存到 DB,所以在执行测试时,只需要 监听 事件队列,即可在监听的事件队列中按照需要保存和获取需要断言的事件。点击事件发送的数据结构大致如下:

对事件数据的校验,首先保证字段完整且每个字段不为空,即数据的 Schema 正确;其次根据需要对事件的具体字段做校验,比如点击事件的类型 t 应该为 clck 。这些检查被封装到了单独的 Check 方法中,如果检查通过则方法返回 Passed。这里是通过 ClckEventCheck 方法完成了具体的业务校验。

执行测试用例

主要介绍下如何通过命令行执行测试。

安装 Command Line Tools(命令行工具包),App Store 安装 Xcode 默认不会安装 Command Line Tools,可以通过在命令行输入以下命令进行单独安装。

xcode-select --install

在使用命令行执行测试之前,还需要将项目设置成 Shared。打开 Product → Scheme → Manage schemes,查看项目是否是 Shared,如果不是,则选中后面的复选框将其共享。

命令行执行所有的测试用例

xcodebuild -workspace Growing.xcworkspace  \
-scheme GrowingIOTest test \
-sdk "iphonesimulator13.5" \
-destination platform='iOS Simulator',OS=13.5,name='iPhone 11'

执行单个用例

xcodebuild -workspace Growing.xcworkspace \
-scheme GrowingIOTest test \
-only-testing:GIOAutoTests/ClckEventsTest/test7DialogBtnCheck \
-sdk "iphonesimulator13.5" \
-destination platform='iOS Simulator',OS=13.5,name='iPhone 11'

更多xcodebuild 的使用方法可以,参考其使用说明

man xcodebuild

美化测试报告

xcodebuild 的输出阅读起来不是太直观,使用 xcpretty 可以解决这个问题,并且它还能完成测试报告生成。

xcpretty 是一个高速灵活的 xcodebuild 输出格式化工具,其使用如下:

# 命令行安装 xcpretty
gem install xcpretty

命令行执行

xcodebuild -workspace Growing.xcworkspace \
-scheme GrowingIOTest test \
-sdk "iphonesimulator13.5" \
-destination platform='iOS Simulator',OS=13.5,name='iPhone 11' \
| xcpretty --report html

生成的测试报告如下


默认输出 html 报表在 build/reports/tests.html

5. 覆盖率统计

在执行自动化测试的时候,通常我们想获取测试覆盖率报告,以度量自动化测试的覆盖情况。因为 KIF 是直接基于 XCTest 实现的,说以可以很容易的使用 Xcode 自带的覆盖率统计工具。其设置如下:

Product → Scheme → Edit Scheme,Code Coverage 把需要统计覆盖率的被测程序加入到 Targets 中。


测试完成后可以拿到覆盖率统计报告。

6. 持续集成

自动化测试的最大价值在于可以替代人工进行更高效,更频繁的测试。因此要发挥自动化测试的价值,最理想的方案是,将自动化测试加入到持续集成环节中,每当有代码变更时,就自动的执行测试,快速反馈结果。

我们利用 Jenkins 监控代码仓库变更,当有新的 commit 提交时,Jenkins 会自动拉去最新的代码,并调用命令行执行相应的自动化测试用例,收集相应的测试报告,并将测试结果通过钉钉机器人及时的通知给相关的开发和测试人员。当测试失败时,相关人员可以第一时间收到结果,并及时解决。

7. 总结

本文以 iOS 平台为例系统的介绍了 GrowingIO 数据采集 SDK 主要工作原理,测试方案的设计以及自动化测试框架的选型与自动化测试实施。希望对从事 SDK 测试工作的同学有所启发。后面我们还会分享 GrowingIO 用户触达 SDK 的自动化测试,Android SDK 自动化测试等相关的内容,请大家持续关注我们。

参考资料
https://tech.meituan.com/2016/09/02/ios-uitest-kif.html
https://github.com/kif-framework/KIF - Connect to preview
https://github.com/xcpretty/xcpretty - Connect to preview

关于GrowingIO

GrowingIO 是基于用户行为数据的增长平台,国内领先的数据运营解决方案供应商。为产品、运营、市场、数据团队及管理者提供客户数据平台、获客分析、产品分析、智能运营等产品和咨询服务,帮助企业在数据化升级的路上,提升数据驱动能力,实现更好的增长。

如果对 GrowingIO 兴趣,欢迎点击「此处」了解更多!

GrowingIO 数据采集 iOS SDK 测试实践相关推荐

  1. 爱奇艺iOS稳定性测试实践

    稳定性测试是长时间持续运行APP,以验证应用是否稳定的测试.它可以有效发现APP长时间运行下的偶发闪退.内存泄露.性能变差等问题.iOS端通常由苹果系统的API快速执行点击事件,开展稳定性测试,类似的 ...

  2. 网易技术干货 | 云信Web SDK测试实践

    一.项目介绍 网易云信于2015年成立,为网易集团下属的内资公司,总部位于杭州.除资深老杭研外,团队核心90%来自硅谷.百度.腾讯.阿里.华为等大型企业/独角兽公司,平均行业经验10年以上,掌握业内领 ...

  3. 【腾讯TMQ】iOS电量测试实践

    iOS电量相关问题一直是测试人员头疼的事情,电量测试怎么开展.问题怎么复现和跟进定位.用户反馈电量相关的问题我们如果获取更多的信息等等,一直都没有一个好的解决方案,以至于我们面对电量相关的问题时,总是 ...

  4. 客户端SDK测试思路

    本文来自网易云社区 作者:万春艳 是什么 客户端SDK是为第三方开发者提供的软件开发工具包,包括SDK接口.开发文档和Demo示例等.SDK和应用之间是什么关系呢?以云信即时消息服务为例,如下图所示, ...

  5. 集成支付宝钱包支付iOS SDK的方法与经验

    没想到,支付宝的SDK是我目前用过的所有第三方SDK中最难用的一个了. 下载 首先,你要想找到这个SDK,都得费点功夫.现在的SDK改名叫移动支付集成开发包了,下载页面在 这里 的 "请点此 ...

  6. 支付宝钱包支付iOS SDK的方法

    为什么80%的码农都做不了架构师?>>>    文档 压缩包里有两个相关文档 : <支付宝钱包支付接口开发包2.0标准版.pdf> <支付宝钱包支付接口开发包2.0 ...

  7. 急速收藏:4套iOS SDK的H5打通方案

    在介绍 iOS SDK 的 H5 打通方案之前,我们先了解一下什么是 App 与 H5 打通. 所谓 "打通",是指 H5 集成 JavaScript 数据采集 SDK 后,H5 ...

  8. ios使用支付宝进行支付,注意事项 集成支付宝钱包支付iOS SDK的方法与经验。...

    下载 首先,你要想找到这个SDK,都得费点功夫.现在的SDK改名叫移动支付集成开发包了,下载页面在 这里 的 "请点此下载集成开发包" Baidu和Googlep排在前面的支付宝开 ...

  9. 移动广告SDK测试思路

    什么是移动广告SDK 移动广告SDK是嵌入到宿主APP中的一个jar或aar包,其提供了一系列API供开发者调用.这些API可以进行广告请求.广告打点等行为,可以对广告进行渲染.开发者只需要关注自身A ...

最新文章

  1. Oracle查询重复数据并删除,只保留一条记录
  2. 基于python和postgreSQL存储图片
  3. python进行矩阵计算公式_纯python进行矩阵的相乘运算的方法示例
  4. php小数乘法,三 小数乘法精品|小学数学,北师大版,四年级下册,数学精品下载_21精品_21世纪教育网...
  5. HiddenHttpMethodFilter过滤器—SpringMVC
  6. 使用jeDate日期控件
  7. abaqus算出来的转角单位是什么_abaqus中后处理中U的单位是什么?
  8. 台安PLC通过手机热点远程在线模拟,远程编程,远程调试
  9. 项目进度管理-活动历时估算工具技术:三点估算
  10. 摄影系列:单反相机入门知识
  11. Period 、Duration常用方法使用与介绍
  12. CTF-PWN学习-为缺少指导的同学而生
  13. STM32——FLASH擦除/写入失败的踩坑笔记。(WRPERR)
  14. android 执行bin文件是什么意思,将可执行文件复制到android中的system / bin
  15. Android开发效率提升利器-ButterKnife最全使用详解及ButterKnife插件的使用
  16. Matlab画三维图笔记
  17. bilibili怎么用用户名登录_b站怎么用用户名登录 bilibili如何用用户名登录
  18. springcloud-netfilx(Eureka)服务注册
  19. 链接投票二维码制作制作投票链接视频选举投票制作
  20. ANSYS_Maxwell平面电场仿真

热门文章

  1. 前端js,join()方法
  2. [Redux/Mobx] redux的数据存储和本地储存有什么区别?
  3. 「Gitea篇」如何用Git平台账号登录建木CI
  4. VMware16安装MacOS【详细教程】
  5. 各大android应用商店的展示权重 安卓应用商店关键词+下载量+评价+其他这几项占的权重(仅供参考)
  6. 3-6月计算机类学术会议合集
  7. 任务提交SparkSubmit源码解析
  8. 离散数学笔记_第一章:逻辑和证明(1)
  9. bitwarden_rs 搭建自托管的密码服务器
  10. JavaScript 数字格式化怎么写(#,##.00) (实用,赞)