测试作为质量保证极其重要的一环,在移动App开发流程中起到非常关键的作用。从开发工程师到测试工程师,人人都应具备良好的测试意识,将隐患和风险在上线之前找出并解决,可以有效的减少线上事故。
背景
在移动互联网时代,APP大都承载着本公司的各大业务。为了保证质量,需要进行各项测试:冒烟测试、功能测试、集成测试、专项性能测试,回归测试。其中冒烟测试和回归测试大多由开发和测试自己手动执行,有较大的优化空间。一方面,测试的人力成本较高;另一方面,在之前的测试过程中发生过漏测等问题,这些问题在测试阶段被QA发现,又会再次返工,费时费力。
对于基于UI的功能测试的需求其实一直存在,理由其实很简单,不想一直让人去做重复机械的事情,而且可靠性完全是靠人力的堆积产生。鉴于这两部分测试用例相对稳定,不会频繁发生较大的变化,我们打算将其自动化,降低人力成本投入,将测试结果报表化,避免人为疏漏造成的一系列问题。
冒烟测试:就是完成一个新版本的开发后,对该版本最基本的功能进行测试,保证基本的功能和流程能走通。 回归测试:是指修改了旧代码后重新进行测试,确认修改没有引入新的错误或导致其他代码产生错误。
方案选型
目前业界测试方案非常多,如下图:
应该如何选择适合团队的测试方案呢?我们主要考虑以下几个方面:
支持移动端app自动化
我们主要做的是移动端的UI自动化,因此,仅限于PC端webApplication的几个框架就不可避免的要排除掉了,这其中包含Selenium,PhantomJS,以及KARMAR。
支持多平台自动化
此外,对于移动端的UI自动化,我们希望可以同时覆盖安卓以及iOS平台,最好是一套脚本能同时在两个端上跑,鉴于此,只提供单一平台的Selendroid,Robotium可以暂时不用考虑了。
学习成本低
经过上面两次筛选,我们的选择剩下了Macaca && Appium && Calabash,这其中,Macaca以及Appium都是支持多语言的,Appium支持的最多,包含了Ruby Python Java Js OC PHP C#(.Net)这些几乎所有主流的语言,Macaca目前支持Js Java以及Python,也能基本满足需要,相比之下,Calabash只支持Ruby,这个对团队是有一定的挑战的,如果采用Ruby,意味着所有的同学都要先学习一下这门语言,这个成本相对来说是比较高的,因此,Calabash也从我们的待选list中删除。
经过三轮筛选,目前摆在我们面前的有两个选择,Appium && Macaca。
新方案形成
Macaca在2017年我有写过一篇文章讲解《Macaca 面向多端的自动化测试解决方案》,这次介绍一个新的方案,由于QA同学大都对Appium有一定的经验,但考虑到维护成本主要是由控件和脚本逻辑两部分构成,于是新方案中通过yaml文件来维护控件ID、通过封装好的action库来编写脚本逻辑。
第一阶段(优化报告)
报告问题:
- 不能从输出获悉具体的操作目的、失败含义
- 不能有效输出操作步骤、关键操作截图等
- 输出信息有限难以与现有的缺陷追踪系统对接
- 报告的获取方式不友好
- 报告格式不标准不利于归档
- 报告文件占用空间太大(大约250MB)
解决方案:
- 要求脚本提供操作步骤、期望等信息
- 通过集成allure框架标准化测试报告
- 通过Jenkins将测试报告有效归档
- 通过自建邮件报警模块来及时发送测试报告
- 失败的时候才截图
- 通过与jira系统对接实现错误自动上报
总结:
- 初步规范了自动化报告
- 实现了错误监控
- 通过邮件预警及时发送报告结果
- 与缺陷平台对接,方便追溯Bug来源
- 降低了报告的存储空间,节约了服务器磁盘资源
第二阶段(规范脚本)
脚本问题:
- 依赖特定环境运行(不规范构建)
- 依赖特定资源,执行完成后未清理,影响其他脚本
- 容错性差,不稳定,执行效果差
- 造了太多轮子(各自实现了一系列通用操作)
- 部分前置条件依赖手工构造
解决方案:
- 引入flake8做代码质量检查
- 引入Jenkins做环境初始化、统一运行
- 封装基础操作
- 要求脚本结束有效清理资源(账户、设置等)
- 开发辅助APP对测试环境进行容错处理
- 接入STF平台对测试环境做有效清理
总结:
- 规范了脚本的提交和编译过程
- 审核、构建、常用操作的封装大幅提高了脚本的质量
- 依赖辅助APP和STF平台脚本提高了脚本的稳定性
第三阶段(可配置化)
配置问题:
- 解决不同机型的权限弹框及交互的不同
- 打包任务、各自动化任务、报告显示等地方的版本配置信息单独维护,成本较高
- IP变更导致的维护成本
解决方案:
- 通过启动模块提供不同类型的脚本用例并提供配置
- 通过将IP配置动态化
- 通过将被测应用的各种信息维护在数据库,在QA平台提供配置中心来统一管理各地方的配置信息
总结:
- 通过启动模块配置解决了不同机型的脚本兼容性问题
- 通过QA平台的配置中心解决了配置信息维护成本高的问题
第四阶段(自动调度)
“自动”的问题:
- 没有统一的调度、设备资源浪费
- 脚本执行时间不定,而设备分散造成无法协调资源
- 无法自动获取可用的挂载设备
- 开发提交代码之后要手动触发自动化任务
- 因断电等意外情况,造成服务可用性降低
解决方案:
- 搭建云测小屋集群,抽象设备池、集中资源
- 使用QA平台的定时模块,来为自动化任务配置执行时间
- 将QA平台从一个单纯的报告展示平台改造为任务中心
- 通过在github配置webhook实现自动触发打包执行自动化任务
- 通过给集群中的每台机器安装agent来实现设备的自动管理
- 给集群中的每台机器配置supervisor服务用来实现进程管理
工作流程图:
总结:
- 调度减少了自动化的工作量,提高了自动化的效率
- 设备池有效的整合了可用资源
- 通过Webhook打通从开发提交代码到自动化任务执行
- 基本实现了无人工干预的自动化
自动化实践效果
这里将从以下几个维度探讨自动化实施的效果:部署情况、投入产出比、运营数据情况。
部署情况
研发阶段每日运行自动化:BVT(同步启动内存泄漏扫描、静态代码扫描);研发阶段每次提交自动化:MAT;线上版本每日验证:DDC。从部署情况来看,框架适用场景非常多,基本能满足测试需要。接下来的投入产出比和运营数据的讨论,就以UI功能自动化测试(又称BVT)为例进行讲解。
投入产出比
投入产出比的问题要看两个方面,好比天平的两端,一端是投入,一端是产出。得产出重过投入才是一个好项目,值得长期运营。投入产出比如下图所示。
从上图可以看出,我们的投入成本可以分成两块,分别是一次性成本和线性成本。
一次性成本:框架研发 配置和部署 学习成本。一次性成本主要消耗在框架的研发上,以及测试人员的初始培训上,后续只有新加入测试人员才会增加这个成本。事实证明,在一次性成本上的投入非常值当,好的框架可以保证提高后期运维阶段的稳定性和使用的简易性。
线性成本:自动化用例编写(平均5分钟/条),每日需要维护的成本(3分钟)。线性成本随着时间的推移可能会发生变化,例如自动化用例随着测试人员的熟练程度,单条用例的编写时间会减少,每日需要维护的成本随着用例数的增多和需求变动的增多会增高,这些都在预期范围内。
产出主要从客观和主观两方面进行评估。
客观:前置Bug暴露时间。BVT每日运行,因此总会提前于正式提测前暴露问题。目前是部署在主线上,假设产品的迭代周期是2周一般平均从第三天开始有提测需求给到,一旦BVT发现问题,平均能前置3天发现。
减少提测拒绝次数,节省人力时间成本。由于BVT里的自动化用例全部是基础核心用例,一旦出现运行问题,就是不符合准入测试标准的。在没有BVT的时代,提测前都是以开发手工自测和测试手工验证的方式进行,一旦发现不符合测试条件的Bug,就会打回,在这种情况下就会消耗不少的人力和时间。有了BVT后,开发可以自己运行自动化脚本做基础功能自测,测试每日监控也在运行检测。目前机器在夜晚用90分钟左右可以运行完全部用例,假设一台机器相当于一个机器人,那么三台机器就相当于3人 x 90分钟=270分钟,每天节约了270分钟的人力成本。
主观:为什么要放上主观收益呢?因为客观上节省了时间。总之自动化的部署大大提高了测试在项目组的影响力,从此客户端上的测试从纯手工迈入了新时代,每日版本质量也有了持续稳定的检验,全项目组的内心也更加淡定了。
运营数据
发现的问题中主要分为三类,分别是误报(因为脚本的稳定性和测试环境导致的)、UI变动(包含被测元素变动、需求变更)和真实Bug。根据统计的数据可以发现UI变动导致的问题占总发现问题的比例相对较高。另外测试环境的不稳定导致的问题也比较多。
问题与展望
问题
无法将所有用例实现自动化
例如登录验证码的情况,还有涉及多应用交互的场景都比较难覆盖到,另外也不能确保所有控件都能精确获取到。
关于UI自动化的作用
无法完全替代人工,因为有些复杂逻辑和表现需要人工确认,机器容易出现误判,另外UI自动化整体容错性差,需要及时维护,而且不太适用于UI变动频繁的业务场景。
展望
希望可以达到下图这样的效果: