一种基于动态插件系统的移动测试黑科技

百度MTC是业界领先的移动应用测试服务平台,为广大开发者在移动应用测试中面临的成本、技术和效率问题提供解决方案。同时分享行业领先的百度技术,作者来自百度员工和业界领袖等。

本文作者:hyxbiao && tony xin

背景

移动APP插件化是平台化产品解决系统限制(65535)、模块解耦、和多团队协作的利器。它的最大特点是模块动态下发,给产品带来的收益显而易见,但是,在百度,这套系统给移动端测试技术带来了新思路

移动端线上问题定位的几个场景

  • 场景一: 云端用户反馈某功能不可用,RD猜测几种可能触发原因,线上收集的客户端打点日志信息不全,无法完全确认问题。陷入死循环,线上用户持续暴露问题,线下无法稳定复现,不能及时定位问题。如何破?
  • 场景二:通过客户端预埋方式打点用户行为,往往会出现打点不全的问题,而往往线上问题的定位需要这些行为日志为问题定位提供良好的复现步骤。 如何无需编码,通过技术手段获取全量用户与客户端交互日志?
  • 场景三:线下很多好工具可以SDK化,给线上问题发现和定位带来大量正向收益,但因为测试能力本身会影响集成app的性能,或开发团队排期等原因,无法集成,大量线上问题无法充分暴露。如何优美的解决这种问题?
  • 场景四:百度的线上客户端小流量实验表明,线上问题实际是一种正态分布的随机事件,TOP问题,往往只需抽样很少量用户即可召回,而不需要影响全量用户

移动端线下测试的几个场景

  • 场景一: 客户端测试简单却又复杂,一个客户端测试人员的简单技能树可能包括这些问题的分析能力: ANR、crash、卡顿、内存泄露、内存、CPU占用、电量分析、启动速度分析等等一系列的技能。而往往,部分QA人员并不是全栈。并且这些工具的使用本身,就是一个工具大集合。如何让客户端测试人员,或非专业测试人员,无需任何背景,只需要点一点就可以具备全部客户端问题分析能力
  • 场景二:同刚才说的线上问题定位,线下大量的优秀功能,并不能适用于全量用户,因为他们本身就是伤敌八百,自伤一千的能力。如何在尽量小用户体验损耗的前提下,让问题尽量的全部召回?

一种移动端线上问题定位的新思路:

基于插件系统,做一个测试插件,把我们所有觉得有用的线下测试能力打进去,同时集成业内知名的好框架,譬如dexposed、 leakcanary等,还有一些系统开放了但是主版使用会影响性能的好东西traceviewer、Choreographer、ActivityLifecycleCallback等。统统打到云插件中,并通过云端已经构建好的动态模块小流量系统下发到特定目标用户手机中,持续暴露问题

NICE JOB!!

云插件工作原理: 
云插件本身就是宿主的一个插件而已,真正能够发挥它的测试能力的是,线下构建的大量测试场景,以及插件本身的动态加载机制,这样我们的测试场景就可以在线上发挥它的效力了。提到这个就不得不新锅炒旧饭:

  • 双亲委托机制:java的类加载机制下,子classloader可以向上查找父classloader的加载内容,从而给云插件动态查找宿主各种类信息提供了先决条件(多进程化的插件系统。。请忽略我把)
  • dexclassloader:可以加载文件系统的任意JAR(包含dex文件)、zip、apk文件
  • patchclassloader: 只可以加载data/app/的apk文件,常用于多dex拆分项目
  • dexfile: 可以加载动态文件,同时提取文件内部的类信息,这个是dexclassloader不具备的
  • 破壳: 云插件自己的场景需要集成信息上传类,但在编译时,不能将对应类编译进插件包。这样场景插件在被加载起来以后,就可以回调宿主的日志系统进行信息采集了

经过如上,下图中的JAR或APK中包裹的场景插件就可以被云插件动态加载进来,同时对宿主的各种类、本地空间、以及系统中与宿主相关的信息进行读取、采集。至于是hook、反射、代码注入、异常捕获、插桩等这些只是一种手段了

实例:

注意: 下面的case,虽然说的是云插件的问题定位场景,但是不止云插件,我们后面会以SDK形式开源这部分技术,所以,集成了这个SDK的app也可以这么干,但是脱离了插件系统,本身的安全性,需要集成的开发者关注自己的安全性。 当然也可以不关注,root的手机上,你的app本身就已经全部暴露给了黑客(BLESS…)

正文: 以流畅度为例,我们看如何非常快速的构建云调试插件的case吧

流畅度:可以理解为android系统绘制UI的速度,理论上,人眼在1s内接收60帧图像才会感觉程序流畅。 android系统之初,流畅度一直是人们诟病的目标,直到android 4.1系统的时候,有了注明的project Buffer,并引入了三大元素,VSYNC(垂直同步)、Triple Buffer和Choreographer。其中Choreographer这个东西是我们今天讨论的目标。它是整套机制中的协调者,并且所有looper都共用一个Choreographer对象

Choreographer对外开放了一个FrameCallback的东西,在每次系统绘制时,都会通过这个回调doFrame函数,通过这个函数可以计算出在1s内,当前页面的绘制次数。但是问题来了: 
看上图,含义就是,此货虽然好,但是建议是你们开发者还是不要用了。。。这如何玩,本来还想拿它上个流畅度监控的。。此时一定会想到,我们有云调试插件。

构建很简单,如下,只需要把这段代码copy到任意android工程,然后打包,注意NutXError只作为编译依赖即可, 如果已有插件系统, 这段代码就可以直接被加载并运行了

public class        NutFrameMonitor extends BaseCase {    private static final String TAG = "NutFrameMonitor";    @Override    public void invoke(Context context) {        int sdkVersion = 0;        try {            sdkVersion = Build.VERSION.SDK_INT;        } catch (Exception e) {            // TODO        }        if (sdkVersion >= 16) {            try {                Choreographer.getInstance().postFrameCallback(NutFrameCallback.callback);            } catch (Exception e) {                // TODO            }        }    }

    private static  class NutFrameCallback implements Choreographer.FrameCallback {

        static final NutFrameCallback callback = new NutFrameCallback();        private long mLastFrameTimeNanos = 0;        private long mFrameIntervalNanos = (long)(500000000) - 1;        @Override        public void doFrame(long frameTimeNanos) {            if (mLastFrameTimeNanos != 0) {                final long jitterNanos = frameTimeNanos - mLastFrameTimeNanos;                if (jitterNanos > mFrameIntervalNanos) {                    NutXError error = new NutXError(TAG);                    error.setDetailMessage("frame Choreographer waste more than 500ms");                    error.dump();                }            }            mLastFrameTimeNanos = frameTimeNanos;

            Choreographer.getInstance().postFrameCallback(NutFrameCallback.callback);        }    }

}

结果

下面这个截图是在操作客户端运行的时候(注意监控case是通过云插件动态加载的哟),发现的一个流畅度问题。同时也可以看到,在监控到绘制问题后,用户停留的每个界面也被画了出来。 然后线下就可以沿着这条trace去复现结果了~ 
是不是很酷~~~

后记

如上,便结束了对百度在移动端测试的技术探讨。然而,其实有很多没提到,譬如现在已经构建好的自动化case有哪些、这套机制兼容性如何等,再譬如有眼尖的同学也会发现这套系统本身可能就会有兼容性问题,如何做好问题卡控,保证云调试插件(其实我们叫坚果云)有效及时回收。 其实,我们有充足的自信在线上尝试这个东西。在厂子的线上,我们一整套动态模块小流量系统,云插件本身其实就被作为了一个动态模块,当线上出现问题时,我们的云插件就会发挥它的价值了

更多干货分享请关注”百度MTC学院“http://mtc.baidu.com/academy/article

时间: 2024-12-19 01:45:54

一种基于动态插件系统的移动测试黑科技的相关文章

基于android4.4系统行车记录应用黑屏问题分析及对策

基于android4.4系统行车记录应用黑屏问题分析及对策 笔者最近遇到一个棘手的问题,那就是行车记录应用出现黑屏的问题,现象就是进入行车记录应用surface是黑的,录像文件几分钟一个的那种,每个文件的大小都是零.看到这个大家都非常重视,对于车载产品来说,行车记录功能需要保持长时间正常工作,出现这种问题肯定是不能接受的,必须解决!那这个问题是怎么出现的呢? 跟了很长时间,同时动用了8台相同的机器来单独做行车记录的拷机测试,12个小时内都不会出问题,但是超过24小时,就有那么2-3台机器会出现黑

一种基于RBAC模型的动态访问控制改进方法

本发明涉及一种基于RBAC模型的动态访问控制改进方法,属于访问控制领域.对原有RBAC模型进行了权限的改进和约束条件的改进,具体为将权限分为静态权限和动态权限,其中静态权限是非工作流的权限,动态权限是工作流中的权限:将约束条件分为静态约束和动态约束,其中静态约束包括最小权限约束和职责分离约束,动态约束使动态权限按照工作流进行操作.采用本发明的方法改进后的RBAC模型具有以下优势:为传统的RBAC模型中增加了动态特性:跟纯动态模型相比较具有更高的效率:保证需要按顺序执行的权限能够按顺序执行,使得系

浅谈C#中插件系统编写的一种简单方法

1.背景 几年前还在上学时,用C#+反射机制写过插件系统,后来又用MEF写过插件系统.插件系统本身具有易于扩展的优势,所以在实际项目中使用很频繁.即使在B/S项目中,插件的思想也是大行其道,比如前端单页面+AMD编程便可以理解为一种插件机制,以及后台扩展项目统一打包为一个jar放入主系统jar文件中一起发布,也可以理解为插件思想的运用. 这里我们回到C/S插件系统编写的问题上.由于之前诸多项目编写是将插件编译成dll,然后进行解析.这样做有其好处,即宿主中可以对各个模块解析,完成插件间.插件和主

基于 HTML5 WebGL 的故宫人流量动态监控系统

前言 在当代社会,故宫已经成为一个具有多元意义的文化符号,在历史.艺术.文化等不同领域发挥着重要的作用,在国际上也成为能够代表中国文化甚至中国形象的国际符号.近几年故宫的观众接待量逐年递增,年接待量已突破千万,根据故宫的文物特点与开放模式,必须及时建立一套完整的集监控与防患应急于一体的现代化监控系统. 故宫人流量动态监控系统采用 Hightopo 的  HT for Web  产品来构造 故宫 3D 动态可视化场景,通过将现场部署的传感器.监控设备等装置与智能联网设备集成到互联网上,对故宫当前的

一种基于Qt的可伸缩的全异步C/S架构服务器实现(流浪小狗,六篇,附下载地址)

本文向大家介绍一种基于Qt的伸缩TCP服务实现.该实现针对C/S客户端-服务集群应用需求而搭建.连接监听.数据传输.数据处理均在独立的线程池中进行,根据特定任务不同,可安排负责监听.传输.处理的线程数目,从而在高传输负荷.高计算符合上达成取舍.数据处理采用流水线结构,以避免少量客户的密集计算请求影响其他客户端的处理.本文对应的代码符合LGPL协议,可直接从https://github.com/goldenhawking/zpserver下载. 也可从http://download.csdn.ne

一种基于Qt的可伸缩的全异步C/S架构服务器实现(一) 综述

本文向大家介绍一种基于Qt的伸缩TCP服务实现.该实现针对C/S客户端-服务集群应用需求而搭建.连接监听.数据传输.数据处理均在独立的线程池中进行,根据特定任务不同,可安排负责监听.传输.处理的线程数目,从而在高传输负荷.高计算符合上达成取舍.数据处理采用流水线结构,以避免少量客户的密集计算请求影响其他客户端的处理.本文对应的代码符合LGPL协议,可直接从https://github.com/goldenhawking/zpserver下载. 也可从http://download.csdn.ne

CloudNotes之桌面客户端篇:插件系统的实现

[CloudNotes版本更新历史与各版本下载地址请点击此处] [CloudNotes中文系列文章汇总列表请点击此处] [查看CloudNotes源代码请点击此处] 有时候,同一个名词,针对不同的人群,应该采用不同的表达方式.比如插件的概念,对于程序员而言,可以将其称为插件,或者扩展.对于用户而言,或许"扩展功能"一词会更加贴切.本文还是脱离不了码农的气质,继续讨论技术问题,因此,我会以"插件"一词进行描述. 概述 从1.0.5504.38654版本开始,Cloud

OSGI(面向Java的动态模型系统)

基本简介编辑 OSGI服务平台提供在多种网络设备上无需重启的动态改变构造的功能.为了最小化耦合度和促使这些耦合度可管理,OSGi技术提供一种面向服务的架构,它能使这些组件动态地发现对方.OSGi联 OSGI 盟已经开发了为例如象HTTP服务器.配置.日志.安全.用户管理.XML等很多公共功能标准组件接口.这些组件的兼容性插件实现可以从进行了不同优化和使用代价的不同计算机服务提供商得到.然而,服务接口能够基于专有权基础上开发. 因为OSGi技术为集成提供了预建立和预测试的组件子系统,所以OSGi技

OSGI 面向Java的动态模型系统

OSGI (面向Java的动态模型系统) OSGi(Open Service Gateway Initiative)技术是Java动态化模块化系统的一系列规范.OSGi一方面指维护OSGi规范的OSGI官方联盟,另一方面指的是该组织维护的基于Java语言的服务(业务)规范.简单来说,OSGi可以认为是Java平台的模块层. OSGi服务平台向Java提供服务,这些服务使Java成为软件集成和软件开发的首选环境.Java提供在多个平台支持产品的可移植性.OSGi技术提供允许应用程序使用精炼.可重用