原创 浴风 淘系技术 4月16日
本文根据4月15日淘系技术前端团队出品的「阿里淘系用户体验优化前端实战系列直播」——《通过真机实现页面自动化适配》整理而成。
引言
作为前端大家是否遇到过在项目快上线的时候在某种机器上测试出有兼容性问题,自己一个人在机房debug看看原因是什么以及如何解决?大家又是否遇到过项目上线后在某个业务方tl的手机上出现了页面展示问题,然后自己到业务方工位被一群业务围住现场debug问题?是的作为前端,页面的兼容性问题是影响用户体验的问题,一直是我们需要重点保障的一个问题,保障消费者体验的一致性是我们的职责。今天的主题将为大家分享一种新的方法去保障我们的这个职责,减少我们的窘境。
01
典型体验问题及业务背景
常见几类用户体验相关的问题,以及问题所在的复杂业务场景
02
详细设计
针对复杂业务场景,如何设计系统和方案去解决我们面临的问题
案例分享
03
几个典型案例,以及扩展场景的应用案例分享,
来说明如何应用这样的一套方案
典型的体验问题
我们所说的体验问题到底是什么样子的呢?上面为大家列举了我们实际遇到的几类,第一个是某个业务在某个机器的某个app上出现了页面被放大,从而导致货品展示被截断了;第二个是某个页面在用户浏览时出现了商品展示图片缺失以及价格展示位NaN,第三个是某个页面在用户输入了特定文本后出现了null的提示文案,这些问题都是影响到了实际用户体验的问题,有些属于前端的适配,甚至有些是服务端返回或者运营投放导致的,当被用户看到小则一笑而过认为这个产品前端没有处理好,大则可能直接提了一个舆情。所以我们需要一套很好的方案去减少这类问题的出现,更好的以及更及时的发现这些问题,保障我们用户的体验。
复杂的业务背景
好的解决方案离不开特定的业务场景,现阶段随着业务的不断发展,我们的业务场景也变得逐渐复杂,不再是单一状态、单一app的适配问题。以用户增长的业务举例:用户增长负责在其他的一些app里面通过权益、货品等手段触达用户,然后将用户引导唤端至手淘、再在手淘里面承接用户引导其购买转化。
我们的产品业务可能是多状态的。比如进来时候的红包弹层、催用弹层、详细面板弹层以及分享之后的回流弹层等。其次这些页面可能被投放到各个合作的app里面去触达用户,比如二方的:UC、支付宝、优酷,甚至三方的:爱奇艺、百度、头条、快手等。再者因为用户群体的庞大,用户使用的机型也分布广泛,小米、华为、oppo、荣耀、甚至联想、360、诺基亚等。
传统的适配方法有两种:第一种我们通过制作多个账号、然后使用这些账号去登陆、再由外包同学扫码、通过人工比对的方式去判断我们的页面兼容性是否良好,第二种是通过我们制作不同的mock码去模拟各个状态、再有外包同学扫码通过人工对比去完成兼容性适配。无论哪种方案对于我们这种多状态、多机型、多app的X乘场景都是工作量巨大、耗时耗力的。其次对于一些扫码功能隐藏得很深甚至没有扫码能力的app比如“美图秀秀”更是变得无能为力。
详细设计
▐ 设计思路
我们该如何去解决这些问题呢?首先我们分析问题所在的业务特性,我们的业务横跨多个端,淘宝、支付宝、优酷这样的的一方二方app,甚至抖音、头条、快手、微信这样的三方app,那么我们基于客户端能力的方法就失效不通用了;其次我们的业务横跨了多个技术栈,H5、小程序、WEEX、轻应用,那么我们基于浏览器能力的方法也会变得无力,所以我们需要一种不依赖于客户端不依赖于技术栈的解决方案。
我们同多个团队同学进行了沟通和调研,发现有两个技术现在正在逐渐发展成熟,一是真机技术、二是视觉技术。真机技术使得我们可以通过代码命令调度机器去完成很多事情,比如:截屏,录屏,滚动、点击、输入甚至文件操作、APP操作等。视觉技术随着opencv和机器学习的发展,图像识别、文件识别等能力变得比较成熟,并逐渐可以被作为判断标准使用,于是我们有了去构建一个以真机和图像为基础的自动化框架的思路,这样的一个方案是与app无关、与开发技术无关的。
▐ 核心交互
根据识别结果断言
断言
使用ADB命令打开应用
基于ADB屏幕截图
基于ADB执行操作
截屏
执行操作
获取操作行为
识别
打开应用
根据结果获取操作行为
图像识别元素及位置
▐ 能力推导
有了这样的一个核心流程之后,我们还需要一些其他能力,才能使得整个方案能完整的跑起来,我们从功能性、稳定性、易用性三个方向去考虑这些能力该如何建设。
首先是功能性方面:对于那些没有扫码能力的app,我们需要借助adb+scheme去打开app,而每个app的scheme是不同的,所以我们需要借助业务以及技术的手段去构建一个scheme池,这里面涵盖我们业务所涉及的常用的scheme形式。
其次我们的业务多以人群和设备的维度呈现出不同的功能,所以我们需要去管理一个账号池和设备池,并能够让这些池子有个动态扩张、更新的机制,比如随着业务的发展,定时的去统计常用的机器,以扩展我们的测试设备池。
再者我们业务增长快、业务多状态交互,我们需要一套具备强扩展能力和动态性的解决方案去适应各种业务场景,我们选择构建一个js脚本解析器+一些通用的js api函数的组合形式,使得各个业务能够通过自定义脚本去定制自己的适配流程。
在机器的调度上,对于无登录或者支持多点登录的场景,我们需要支持并行机器调度的能力以提升效率,对于一些强登录、单点登录的场景,我们需要支持按账号串行的调度机器,甚至对于多个任务使用同一个设备这种冲突情况,我们需要一个排队调度机器的能力。
对于同一个任务我们有重复定时执行的诉求,因此我们需要一个定时任务的机制。在任务执行完成或者发现异常以及一些通用的自定义提示场景我们需要及时的通知与反馈,因此需要有消息体系去管理这些通知。
在稳定性方面,一个任务执行可能长达数个小时,期间受机器状态等影响可能会出现一些异常,因此我们需要一些任务执行异常的异常处理逻辑。其次是日志debug系统,帮助我们及时的调试脚本执行的逻辑,快速找到问题以修改。对于一个任务我们也需要去监控他执行的状态和结果,关注他的状态,所以需要任务监控体系。
对于一个系统,易用性也同等重要,脚本的编辑时我们需要一个良好的脚本编辑器,具备语法校验和api提示等通用辅助功能。其次对于一个通用的执行逻辑,我们可以通过脚本录制去快速的生成我们需要的脚本。然后对于一些通用的高频的场景,我们可以把他们抽象出基础能力,直接通过勾选机器、app就可以创建任务,而非一定要手动写脚本,比如对于通用的h5页面多app的打开测试。
▐ 整体架构
脚本录制
任务监控
脚本编辑器
异常处理
日志系统
通用功能
消息体系
定时任务
调度策略
设备池
账号池
scheme池
真机操作API
JS脚本引擎
图像API
测试机
APP
▐ API设计
在api的设计上,为了能够更好的和机器交互,使它能够更好以及更简洁的完成我们的任务,我们把api分为5类:app操作、图片操作、基础方法、行为操作、同时包含一些常用的复合功能。
app操作包含:安装app并处理通用的app设置逻辑、比如授权权限这类弹窗;通过scheme去打开app;在某个app中去打开我们的h5页面;以及判断当前系统是哪个app,用于判断crash或者唤端是否成功;关闭app、卸载app等。
图片操作包含:获取当前屏幕截图、或者当前屏幕中文字的位置、获取屏幕中某个局部图片的位置、对比图片的兼容性相似度、以及上传图片到手机相册等。
基础的方法包含:执行特殊的adb命令、等待时间、保存结果、记录日志等api。
行为操作api可以去模拟用户的基本行为,包含:滚动、点击、返回、输入等操作。
复合功能类api包含一系列常用api的组合去处理常用的功能,如:处理各种系统、app弹窗、站外H5登录、一些常用app的登录封装、发送钉钉消息等。
以上便是目前的整体架构设计和api设计思路。
▐ 适配流程
基于这样的一套解决方案,以一个标准的h5页面适配流程为例:首先我们正常的开发我们的页面或者局部模块,然后我们可以构建mock数据用于联调和展示,在开发完成之后我们便可以基于mock数据定义各标准状态的截图,然后我们通过scheme池获取到待测试app的打开h5的scheme形式,之后我们就可以编写测试脚本,通过api打开h5页面,然后模拟用户的行为操作页面,再关键状态截图与标准状态对比。之后把这样的脚本在多个机器和app上运行,便可以获取到这个页面的“多状态”X“多机型”X“多app”测试报告数据。
使用案例
接下来我们看两个实际的使用例子
▐ 使用案例一
搜索框
搜索结果页
搜索中间页
推家
推案
Adida阿渔达斯儿童鞋新款...
搜索历史
制阵记录
搜素发现
¥229
进尼龙人童爱优中连新省东南连饮会品商理节会
程
疯狂批购中
买课
AdIdas阿达斯儿童鞋2020
活动买二送一
二村精店力
¥229
疯狂地购中
ADIDASH达所儿童事2020
¥229
88拼
甲卖雪101司m..
英
D
疯狂抢购中)
淘
u
AdidaS阿达斯童砖2020秋
打并AP
安莉芳官方球舰店
法店,
s
H
A
¥169
x
z
v
B
N
M
adidas阿迪达斯儿童育装20
关注首单优惠频道
前往
123
中
关注)
我们在平台里面创建这样的一个任务,选择机器、并编写自定义测试脚本。
设备管理2已开启
1.使用app去打开页面并截图
1tm6whshowErroratruestargethttp32F2Fp
constpageurtE"https:/evIewCook-dev.m.tao.cooxpaq
Letschemessnssdki4://noveLuum
//关闭aPP
awaitcloseApp(com.ssandroid.rticlew)
1/打开app
awaitopenAppByscheme(scheme)
awaitsleep(10000;
Letopenpicawaitgetscreen;
信息创造价值
savepicttname"打开appur:opeic)
2.查找并点击搜索框后截图
etsearchTextawaitgetscreenText("搜索发现")
Let
if(searchText)return;
awaittap(searchText.position);
letcuickpicawaitgetscreenur;
savePic(name:"点击搜索框,urt:clickPic));
四不山皮承
LetsearchbuttonawaitgetscreenText("搜索")
awaittap(searchButton.position)
LetsearchpicawaitgetScreenur);
icttroeunlhtp//g.
Letcompatibilityatcma
savePicCiname:"点击搜索url:searchpiccompatitu
1/关闭app
3.查找并点击搜索按钮,截图并对比兼容性
awaitcloseApp('com.ss.android.articlenes
头条今日头条
▐ 使用案例二
第二个是利用脚本去做线上页面巡检的例子,在充值中心业务中,我们期望定时的去执行任务,输入不同的省、市、运营商的手机号,并判断页面上针对这个手机号是否出现异常展示。同样是在平台创建一个任务然后脚本逻辑中,第一段通过scheme去打开充值中心页面,第二段找到输入框,然后最后通过一个for循环对96个不同省、市、运营商的号码输入、判断有没有异常展示,并清空输入框、输入下一个手机号码。
运行中一旦出现异常便会通过钉钉告警。
好处
我们在多个业务中使用了这样一套方案去帮助我们完成适配以及线上页面的巡检任务,发现有三个方向的好处,首先通过脚本调度机器完成任务,减少了测试成本,提升了我们整个项目的测试效率。其次,这些脚本可复用,我们在做了一个项目的技术迭代后,直接可以回归验证,无需重新编写。再者,我们借助定时任务,可以定时去巡检我们的线上页面,持续的保障产品的质量和消费者的体验。
优缺点
这样的一套方案,对比传统的自动化测试框架有优势也有不足,首先优势是:通过真机执行,更好的能反应用户的真实环境,其次调度机器的链路短,更稳定,二是这样的方案是不依赖开发语言和待测试的app的,更不依赖于代码的实现,脚本的编写也相对简单,只需要一些核心的api就可以完成大部分工作。不足处在于:断言依赖于图像的识别能力,没法深入到请求数据、页面的dom节点结构等。
解决问题归类
基于图像识别的断言我们可以解决这几类问题:检测页面上是否有特殊字符 undefined null等判断页面是否展示不全,空窗、元素丢失等检测页面是否出现了异常,如白屏、无效的链接、crash等以及其他的一些通过图像和app层判断的断言类型。
扩展场景
这样的一套方案在保障用户体验上除了用于做适配和定时巡检,我们还可以用在其他的一些场景。
▐ 素材监测
比如针对我们投放的素材监测链路,我们可以通过真机模拟用户行为去浏览一些合作的app,当发现我们投放的广告素材时,点击看看承接链路是否正常以及唤端链路是否正常。
▐ 开屏监测
第二个是我们通过真机去打开访问一些app,去识别出一些开屏广告,去判断他的唤端和承接链路是否正常以及判断投放的这些素材是否有损用户体验。