背景
埋点对电商类 app 的业务倒退始终有着重要的指导作用,然而其简单的数据组成使得它的稳定性难以失去保障,往往业务逻辑的一些重构就会导致一些埋点属性甚至是整个埋点的失落。
也正是因为埋点具备多个数据源,惯例的自动化验证只能验证埋点是否存在,无奈跟业务场景匹配。而对于人工排查来说,尽管能解决和场景匹配的问题,然而像不同埋点的属性之间的关联或者属性和接口字段的关联这类简单的校验做起来也十分的艰难。
本文将介绍咱们是如何通过 teslaLab+ 埋点验证平台实现了埋点的主动回归以及多维度的埋点校验,并在最近三个版本中累积发现了数十个埋点问题。
安卓
IOS
痛点
一个埋点中的数据次要由三个局部组成:
- 接口下发数据
- 用户行为
- 本地运行的代码
要想验证一个埋点是否合乎预期的设计,要害的难点就在于如何固定住这三个数据源,使其每次生成的后果都保持一致或者合乎咱们预约的规定。因而咱们别离采纳了以下计划来实现埋点生成时数据源的固定
- 接口数据:对接口 mock 实现了对接口数据的录制 & 回放
- 用户行为数据:通过谷歌的 uiautomator 来实现用户行为的录制 & 回放
- 本地代码:和 ab 平台买通,通过动静调整 ab 配置下发接口来最大限度上固定客户端 ab 试验相干的代码。
概览
名词解释
- teslaLab:是一款无线测试工具(MAC/WIN 利用),提供开箱即用的无线性能 / 体验 /UI 自动化 等专项测试工具。
- ubt-verification:安卓侧实现埋点数据录制和接口 Mock 性能的 SDK。
- 测试场景:即校验规定组,对应着一个测试用例,蕴含了这个 case 的所有埋点校验规定
- mock 记录:蕴含了一个 case 在运行过程中申请的所有接口的数据,用于自动化回归时进行接口 mock。
- 测试记录:自动化回归的产物,即录制到的所有埋点数据。
- 验证报告:即测试记录和测试场景的联合产物,蕴含了所有异样埋点的具体异样信息。
- 工作组:来自 teslaLab 的概念,即测试记录的汇合,个别用于聚合各业务线的测试记录。
- 通过率:指一个测试记录中没有任何埋点异样的埋点(去重)占埋点总数(去重)的百分比。
- 工作组通过率:指工作组中所有测试记录中没有异样的埋点总数之和(去重)占所有埋点总数之和(去重)的百分比。
零碎架构图
整个埋点自动化验证平台次要由三局部组成,别离是:
- 自动化工具:teslaLab
- 挪动端 SDK:安卓的 ubt-verification 和 ios 的 kylin
- 验证平台:无线研发平台的埋点验证模块
流程图
下图为单个测试用例的首次验证流程:
次要可分为三个阶段:
- 筹备阶段
<!—->
- 用 teslaLab 录制或者编写自动化脚本
- 在脚本编辑页手动执行脚本并抉择录制 Mock 性能,录制接口数据并创立 Mock 记录
- 新建运行工作并选中后面新建的脚本和 Mock 记录,执行工作之后失去一组埋点数据(即测试记录)。
- 依据须要验证的埋点的数量自行抉择手动配置(不举荐,太麻烦)或者从上一步失去的测试记录中主动生成(举荐)相应根底规定(即测试场景)。
- 至此,埋点自动化验证的三要素(自动化脚本,Mock 记录,测试场景)已集齐。
<!—->
- 运行阶段
<!—->
- 能够手动执行或者通过配置 Cron 表达式实现定时执行在筹备阶段新建的自动化工作,产出一份测试记录和一份验证报告。
<!—->
- 验收阶段
<!—->
-
依据预约策略和测试记录主动生成的验证规定可能无奈满足预期,因而产出的验证报告中的问题须要人工核查是否无效。
- 如果有效则能够通过报告详情页中的修复按钮疾速勘误规定,或者返回测试场景详情页手动勘误规定。
- 如果无效则能够选中无效的埋点并提交报障至埋点治理平台,提交胜利后会飞书告诉至最初一位负责该埋点的研发和测试,当问题修复并被测试验收之后即可验收报障。
- 至此,一个测试用例的残缺验证流程完结。
详情
接下来将依照验证流程的程序逐个介绍这三个模块的具体流程
自动化模块
埋点自动化依赖「Tesla-lab 」 的自动化模块,其中数据 Mock 记录的录制和 UI 自动化 脚本的录制依赖「Tesla-lab」 本地编辑器,工作和工作组的定时执行依赖「Tesla-lab」 任务调度模块,工作的理论执行依赖「Tesla-lab」 工作执行器。
「Tesla-lab 」自动化流程图
「Tesla-lab 」自动化整体架构实现
实现上分三个模块:
- 端
<!—->
-
- 编辑器端,负责脚本编辑和数据录制
- TeslaLab 客户端负责本地脚本 / 工作的调试 / 执行,定时工作的部署
<!—->
- Core-local java agent
<!—->
-
- 本地外围服务,封装了基于 Quartz 的工作 / 工作组
- 本地设施治理
<!—->
-
-
- iOS 基于 tidevice / wda
- Android 基于 uiautomator2
-
<!—->
-
- 自动化工作理论执行者
<!—->
-
-
- 基于 pytest 的脚本执行器
-
<!—->
- TeslaLab 服务
<!—->
-
- 提供脚本治理
- 工作 / 工作组治理
- 设施远程管理和同步
「Tesla-lab 」自动化录制编辑器
编辑器 / 录制器(客户端内嵌 Web)
- 录制脚本
<!—->
-
- 反对手动编写或者通过点击页面生成对应代码,反对运行 / 暂停来调试脚本
- 数据录制,通过和挪动端 SDK 进行本地的 socket 通信,触发 SDK 的接口 / 埋点的录制 / 回放流程
<!—->
-
- Mock 接口数据录制
「Tesla-lab 」自动化工作执行器
- 回放工作创立
回放工作的创立会通过 本地 socket xxxx 端口新建一个本地工作,同时会创立一份远端工作。这样能够通过 Lab 的装置主动同步工作到本地,TeslaLab 的外围本地工作和数据都是通过 agent 模块和服务端进行交互。
- 回放工作运行
工作反对立刻执行或者通过配置 Cron 表达式来实现定时执行,工作具备爱护机制,在遇到利用 crash 或者 anr(脚本停滞超过肯定工夫)时会尝试从新开始工作,并且单个工作执行总耗时超过肯定工夫则会提前调用完结录制的 api 来跳过该工作。
- 回放工作后果
执行结束后可通过在工作配置中开启飞书告诉来获取工作组或者工作的执行后果,蕴含工作的执行详情。也能够间接在工作列表页点击开展查看该工作的历史执行记录,记录中包含执行期间的截图和 logcat 日志。
- 「最佳实际一 」 一个工作关联一个脚本。每个脚本关联一条 Mock 记录和一个测试场景。
关联 mock 记录和校验规定,反对含糊搜寻
- 「最佳实际二 」 正当利用工作组,工作组能够依照产品线或者业务线进行创立。
- 实现通过 TeslaLabEngine 单例模式实现 API 的收口。同时,TeslaLabEngine 能够做为独立的 Jar 包接口和前端界面进行解除耦合,能够独自应用。
- 「最佳实际三 」 正当利用飞书告诉,进行工作 / 工作组的排错。
报告示例:
- 「最佳实际四」利用 Cron 表达式实现每日凌晨定时执行工作组,用于继续关注自动化运行的稳定性。目前一个利用的所有工作均在同一个工作组中,每天凌晨 0 点定时运行,其工作组的通过率即为当日的通过率指标,用于监测自动化运行的稳定性。
「Tesla-lab 」演进方向
在将来,依靠云真机平台实现本地调试,云端部署和运行能力,实现更加自动化 / 智能化的形式,再联合客户端丰盛的异样采集策略将埋点缺陷,客户端缺点尽早,尽快发现。
数据采集 SDK
挪动端的数据采集 SDK 均由 teslaLab 通过 socket 通信调起,无交互界面。
安卓侧为独立 sdk:ubt-verification,ios 测则是依赖于线下性能测试工具 Kylin 实现。
整体架构图
流程图
挪动端 SDK 的性能次要有录制 Mock 数据和录制埋点数据两个流程:
筹备阶段
- 在端上通过三方工具 nanoHttpPd 启动服务,收到 teslaLab 调用之后开启 mock 录制流程
- 在本地生成记录 id 等参数,和 teslalab 传参一并缓存至本地,随后重启利用
录制 Mock 数据
- 重启后开始执行自动化脚本,同时将通过拦截器取得的所有的网络申请 request&response 详情上报至后端
- 脚本执行结束后 teslaLab 将调用相干接口进行端上的录制流程,同时 SDK 调用 mock 记录创立接口
录制埋点数据(即自动化回放)
- 重启后开始执行自动化脚本,所有的网络申请将在收到 response 之后调用后端接口获取与其 request 匹配的 mock 数据并替换。
- 所有监听到的埋点数据将被异步存入本地数据库,同时会有一个定时循环执行的工作从数据库中分批读取埋点数据并整合上报至后端。
- 脚本执行结束后 teslaLab 将调用相干接口进行端上的录制流程,同时 SDK 调用测试记录创立接口
埋点数据采集模块
安卓实现
次要通过反射对神策 sdk 实现动态代理,在代理中实现埋点上报时的回调,并在回调中将埋点数据通过 eventBus 抄送至负责埋点上报的治理实例中,进而存储至 sqlite。后续在埋点上报阶段将分批从 sqlite 中取出埋点数据并通过接口上报至后端。
IOS 实现
神策 sdk 埋点记录时有对外的告诉,iOS 监听神策埋点告诉即可取得埋点数据。
接口 Mock 模块
安卓实现
通过对 okhttpClientBuilder 类的 build 办法进行插桩,并应用 addInterceptor 办法退出自定义拦截器,用于实现接口数据的录制和接口的 Mock。这里咱们是通过是否蕴含业务自定义的拦截器来判断以后的 okhttpClient 是否为咱们须要插桩的指标 client。
在拦截器中即可对接口数据进行录制或者是 mock。
IOS 实现
通过 NSURProtocol 对网络进行拦挡,有申请发动时,申请 mock 服务接口判断是否有 mock 数据,申请到 mock 数据就构建响应返回 mock 数据,没有申请到就失常发动申请。
socket 通信模块
安卓实现
通过引入三方工具 nanoHttpPd,在挪动端开启服务,mac 客户端端即可间接通过 IP+ 端口的形式调用到在挪动端实现的 get/post 接口,从而实现和自动化工具 teslaLab 的交互。
IOS 实现
通过引入三方工具 GCDAsync,在 iOS 客户端开启服务,交互逻辑同 Android。
稳定性监控模块
- 本地记录埋点录制的总量,mock 是否胜利开启,包的 md5 值 / 包 id 等信息,追随埋点上传至后端,用于监控自动化回归的运行稳定性以及发现问题后的排查。
遇到的挑战
在稳固运行了一个版本之后,安卓侧忽然呈现了大规模脚本执行失败问题,经排查运行截图定位到是商详接口的 response 产生数据结构的变更,导致应用后期录制的接口数据进行 Mock 时无奈实现数据解析,主动降级切换到 CDN 数据,从而导致页面元素无奈被脚本辨认。
咱们在晚期有布局到这种状况,所以实现了对接口数据结构变更的自动检测以及修复揭示,然而这里的商详接口却并没有触发任何揭示,最初经排查发现咱们录制到的 Mock 数据是风控 sdk 加密后的 response:
初期咱们是为了录制到残缺的 request 和 response 数据,所以将拦截器放在了拦截器列表中最初一位。然而理论运行中应用层并不需要这些拦截器增加的额定参数,因而咱们将拦截器前移到第一位,并且从新录制这些波及商详接口的 Mock 记录。最终修复后脚本运行恢复正常。
平台
整体架构图
无线研发平台:
- 测试场景模块
- Mock 记录模块
- 测试记录模块
- 验证报告模块
埋点治理平台
- 埋点报障模块
流程图
埋点验证 & 验收流程
- 通常一个测试用例中的埋点都有几十个,因而举荐在构建场景时间接从测试记录生成默认规定。
- 通过生成的规定产出的验证报告的通过率个别在 50~70%,这是因为局部埋点属性的必传属性不是固定的,通常在不同的场景会有着不同的体现。然而生成此规定的时候是依据埋点治理平台返回的埋点信息生成的,因而须要将这部分规定进行勘误,能够在验证报告详情页中通过快捷键间接一键修复,或者手动进行调整。
- 勘误之后从新进行校验,产出的报告通过率通常会晋升至 75% 左右,剩下的异样局部通常由一些随机因素导致(例如工夫戳,页面浏览时长)。此时残余问题较少,能够间接人工尝试复现,经确认后即可抉择埋点并提交报障至埋点治理平台。
- 埋点治理平台将发送飞书告诉至最近负责过此埋点的研发,研发修复问题之后会飞书告诉最近负责过的测试,经测试和报障发起人验收之后报障流程完结。如果问题在修复或者验收阶段停留超过肯定工夫将回升并飞书告诉负责人 leader。
最佳实际
依据最近几个版本的用户反馈和总结,目前的最佳实际为:
- 从测试记录主动生成根底规定,并用于产出验证报告。
- 依据报告后果,在报告详情中应用快捷键对必传规定进行疾速修改,并再次触发验证,失去报告。
- 间接尝试人工复现报告中残余的问题,确认后间接提交报障至埋点治理平台。
测试场景模块
为了从多方面对埋点实现充沛的精准校验,咱们依据埋点的内容将用于验证的规定划分为埋点维度和属性维度:
- 埋点维度
<!—->
-
- 埋点的数量
- 埋点之间的时序关系
- 是否反复上报(1s 内上报屡次)
<!—->
- 属性维度
<!—->
-
- 是否必传
- 是否可空
- 取值范畴
<!—->
-
-
- 枚举类型
- 多层嵌套 JSON 数组
- 数字区间
-
<!—->
-
- 属性值之间的映射(例如 tabId 和 tabName)
- 正则校验
- 和 mock 记录中接口数据的映射(例如金刚位的埋点有局部属性的值来源于接口下发)
并且每一个规定都可选强 / 弱校验,区别只在于弱校验不会影响到最终的通过率指标
遇到的挑战
- 一个运行时长 1 分钟的测试用例,假如可能录制到 100 个左右的埋点,去重后大概 40 个,每个埋点须要验证的属性均匀约 7 个,这意味着每一个 case 都须要手动点击 4073*3=2520 次能力实现根底规定的配置,这显然是不可承受的,所以咱们实现了从录制的埋点数据中依照预约策略主动生成默认规定,这样只须要保障录制的埋点数据失常,即可实现最根本规定(包含埋点数量,是否必传,是否可空和取值范畴规定)的构建。
- 对于首页的一些的曝光埋点来说,大部分 case 都会上报,并且其规定基本一致,所以为了防止反复配置节约人力,咱们实现了全局场景,并依照配置的优先级和一般规定进行整合,目前已用于首页曝光埋点的接口映射规定配置。
- 局部埋点属性的值是间接将算法下发的数据和接口数据合并的后果,这类数据个别为嵌套层级较深的 JSON 数组,因为数组中元素是无序的,因而枚举类型不能满足其取值范畴的校验。为此咱们通过递归将问题简化为 JSON 对象之间的比照来寻找差别,实现了针对这类简单层级 JSON 数组的规定提取,规定校验和规定修复。
- 埋点的详情数据均来自埋点管理系统,主动生成的规定也是依据埋点治理平台中埋点属性是否必传的标注来生成,然而大部分埋点属性是否必传并非相对状况,在不同的利用场景下可能必传也可能不用传,这导致咱们产出的验证报告中始终有大量噪声。为此咱们实现了在报告中对规定疾速修复以及接口映射规定,在迅速打消噪声的同时也建设起埋点数据和接口数据的映射关系,从本源上对埋点数据进行校验。尽管在修复上线后因为商详接口的问题整体的验证报告通过率并未大幅度晋升,然而在修复后的单个版本就发现了数十个埋点问题。
Mock 记录模块
- mock 记录由埋点数据采集 sdk 创立,在创立时查看必传接口(ab 配置下发接口,首页的一些接口)是否录制来进行卡口,防止后续产出的报告为脏数据。
- 为了灵便管制 mock 的理论数据,每一个网络申请都会被录制,并且反对开关。对于 get 申请还反对依据 requestParams 来主动匹配对应的 response。
- 为了帮助自动化工具解决弹窗的问题,咱们还实现了全局 Mock,对立将红包弹窗的接口 mock 并返回空后果。
- 接口数据作为埋点数据的重要组成部分,往往决定着自动化回归的稳定性,因而咱们还实现了对接口变更的自动检测,通过比对接口实在数据和 mock 数据的 key 值,寻找数据结构上的差别,生成变更的记录和批改倡议。
并且反对变更的利用和撤回。
遇到的挑战
- 在录制 mock 数据初期,咱们遇到过局部带有搜寻商品操作的脚本会执行失败,经排查发现是端上的实验组代码曾经调整,而 ab 配置下发的接口因为 mock 曾经被固定,这导致原先录制的脚本无奈适配新的实验组的代码。为此咱们引入了事件变更监听,并过滤出所有来自 ab 管理系统的变更事件,再根据事件详情中的 ab 试验 id 去 ab 管理系统获取最新的配置信息,来主动生成用于批量更新 mock 数据的举荐批改后果。
测试记录
- 测试记录列表页
测试记录由挪动端数据采集 sdk 创立,会依据端上上传的监控信息进行比对,如果有异样会飞书报警。
其中红色背景示意记录异样,齐全不可信:
- mock 未开启:即获取 mock 数据的接口产生过非 200 的状况,阐明 mock 未开启或者生效。
- 埋点数量不统一:后端通过埋点上报接口统计到的埋点数量和端上在神策 sdk 的回调处统计的数量不统一,阐明 sdk 存在漏报或者上报接口异样问题。
淡黄色背景示意记录可能有异样,须要排查:
- 即测试记录中的埋点数量和录制的时长比例异样,失常比例约大于 1:1,如果呈现埋点数量小于录制时长秒数,个别为脚本异样,须要人工排查。
- 测试记录详情页
验证报告模块
- 报告的概览会展现报告的根底信息:
- 报告的详情依照埋点聚合,展现了每一个埋点的异样信息及其原始数据。
- 在报告中经人工复现改埋点异样之后即可抉择异样的埋点并提交报障至埋点治理平台,报障的流程与线上报障统一,反对问题打回,测试复测,创建人验收等性能,并且在超时后会主动回升并发送飞书告诉至 leader。
总结
埋点验证平台在每个阶段遇到的痛点其实都是“埋点数据如何固定”这个问题的一个缩影。业务的疾速迭代使得埋点验证过程中积攒的 mock 记录和验证规定这些积淀产物非常软弱,即便咱们通过多种手段实现了这些数据的手动或自动更新,它们最终也难免会彻底生效。因而咱们后续在提取长期有效积淀的同时,也将致力于晋升验证规定和 mock 数据构建的自动化水平,来压缩生效后数据重建的人力老本。
文 /ZHOUXIAOFENG
关注得物技术,做最潮技术人!