9.2专项测试-Android性能测试黑盒分析-1

## 1. 专项测试
* 业务测试:面向新需求
* 回归测试:面向已交付需求
* 专项测试:面向非功能需求的各类质量唯独特征
| 表现 | 用户维度 | 技术维度 |
| 崩溃 | crash,弱网 | 检测崩溃1.某个页面,因为研发处理不合适,点击页面的某个控件、页面加载中接口报错(如返回null值,或空列表)、前端的列表计算有问题(数组越界)、内存问题引发崩溃,一般使用自动遍历、monkey测试频繁的去检测app的健壮性,模拟大量的随机事件。新业务中一般使用断点模拟接口异常,使用自动遍历、monkey测试不一定能有效模拟这种场景。2.还有一些特殊行为也会触发,比如横竖屏切换3.进入一个app,快进快退,也会引发崩溃。 |
| 卡顿 | 掉帧、gc、CPU | 卡顿测试:需要借助与安卓官方提供的技术手段,进行相关的数据分析。原因:CPU使用、GPU渲染,gc,内存泄漏内存泄漏测试method profile |
| 响应慢 | 启动时间、交互响应、H5加载 | 响应时间:分为冷启动与热启动交互响应:界面切换分析起接口调用时间和处理过程H5性能测试:严格分析出来资源的消耗情况 |
| 发热、掉电快 | CPU、MEM、IO、network、GPS等硬件使用 | method profile(了解CPU的使用情况)、gc统计、IO使用、流量消耗、硬件(屏幕等)使用统计、耗电量统计 |
| 兼容性问题 | 机型覆盖、回归 | 兼容性测试、自动化测试、自动遍历、monkey测试主要与机型有关,手机品牌日益聚焦,目前覆盖TOP100就够了。 |
2. 常用的解决方案:
- ddms
* 谷歌开发的安卓分析工具套件,不过逐渐废弃了。 - Android studio最新版本的集成工具
* 关于性能的分析,正在逐渐有独立的工具编程IDE自身的集成。 - 代码插桩
* 可以帮我们发现很多的问题,比如内存的泄漏,对CPU的使用,当前CPU与内存的占用情况,在代码层也可以分析出来。在应用中嵌入一些代码统计指标也可以分析。有些大厂自带了性能监控的SDK,不断统计手机的网络消耗、CPU与内存消耗,上传到服务端进行综合的分析,判断用户有没有出现崩溃、内存不足等手机各方面的数据。
3. 崩溃问题检测
3.1 典型问题:
ANR
假设主线程发起一次网络请求,这次网络请求5秒内没有得到响应,被系统检测到,系统就会弹窗提示ANR。ANR在6.0之前非常多,现在很少了。原因是在开发app的时候,如果在原声页面发起一次网络请求,对于Android Studio来说在编译时就编译不过,会告知这块代码有风险,必须要改,否则编译不过。Force Close
假设页面有一个列表,在处理列表是,出现数组越界,系统弹窗提示Force Close原生的Crash
用C语言或其他语言在底层封装了一些库,结果这个库崩了,而异常未捕捉,也会崩溃
3.2 基本测试方法
- 发布前
* monkey测试+AppCrawler自动遍历:遍历所有的界面,创造一些随机时间,来去模拟能不能触发系统各种诡异的bug
* 结合各类场景用例 - 发布后
* 埋点 在主线程,注册一个异常处理逻辑就可以了
* 接入外部SDK buglly本质在app内注册一个线程的异常处理机制,一旦线程崩溃,他会首先捕获这个异常,把这个异常统计分析,发送到云端
3.3 常见场景
3.3.1 接口返回异常(一般通过Charles或mock来实现)
- 弱网
* 完全超时
* 2G 3G
* 场景:设定一个弱网的情况如2G,或者让响应时间超过3秒钟。进入app,立即退出(可以通过自动化去模拟),此时观察系统有没有出现问题。进入app的时候,应用会发起一个网络请求到服务器。用户发现页面反应比较慢,返回,此时发起网络请求的异步线程还在请求,退出时并未取消请求。请求完成后,就回去渲染当时的页面,如果开发的代码有问题,在异步线程里去渲染一个已经退出的页面即空对象,就会出现空指针。 - null返回:后台的某些接口出现Null或空列表的返回,应用也要能够处理
- 字段类型变更:某些开发随意修改返回值类型,造成客户端崩溃。
3.3.2 逻辑问题:
- 打开新页面再快速返回,异步线程问题
- 横竖屏切换、前后台切换
3.4 崩溃分析
- 1.日志,过滤Exception字段
- 2.traces.txt文件分析,参见https://www.jianshu.com/p/ac3a7c28b830
4. 交互体验
4.1 原生页面响应时间
- app交互
* 冷启动、热启动
* 事件响应、内部加载速度 - 接口性能
- h5加载
4.1.1 冷启动—adb
- 传统的方式,基本已废弃 没有其他相关技术,可以使用传统方式简单统计各个Activity的响应时间,但其时间是不准的。
- 埋点 更多时候是采用埋点,一般一个app会在应用的各个界面进行埋点。比如Activity加载需要多久,这中间又有好几个处理过程,比如去访问服务端获取数据,客户端在获取到数据后再进行渲染。在不同的阶段里面创建自己的埋点,借助埋点去统计各个过程的耗时,这种统计才是准确的。
下面2种统计方式都只统计了Activity的展现时间,里面的数据并未完全加载完。如果想统计数据完全的被加载,还需要另外的统计方法。虽然这2种方法不是特别准确,还是能发现不少问题。
adb shell am force-stop com.UCMobile
adb shell am start -S -W com.UCMobile/com.uc.browser.InnerUCMobile
#ThisTime:最后一个启动的Activity的启动耗时;
#TotalTime:自己的所有Activity的启动耗时;
#WaitTime: ActivityManagerService启动App的Activity时的总时间(包括当前Activity的onPause()和自己Activity的启动)

参考:https://blog.csdn.net/yan_startwith2015/article/details/77991571
```#shell
adb shell am force-stop com.UCMobile
adb logcat |grep ActivityManager.*Displayed
```

4.1.2 冷启动—埋点
为了更准确统计启动时间,一般采用埋点。app会在各个界面进行埋点,Activity加载需要多久,中间还有好几个处理过程,比如访问后端去请求数据再进行渲染,根据埋点统计各个过程。

埋点有2种方式:研发团队埋点、通用的SDK埋点
应用启动(Application onCreate)后,进入主线程(Main Thread),在主线程中初始化Activity(Activity init),创建Activity(Activity onCreate),之后加载事件、渲染布局、展示,此时页面能够展示。除此之外还有异步加载。DisplayedTime和reportFullyDrawn是比较关注的。相比于adb统计,埋点统计更精准。
主要的流程:
- Application OnCreate
* 加载第三方的sdk - ActivityOnCreate
* 加载自身的逻辑
* 发送请求获取数据 json
* 渲染界面 List
使用第三方sdk:
<!--1.集成SDK,在Module的build.gradle文件中添加依赖和属性配置-->
dependencies {
compile 'com.tencent.bugly:crashreport:latest.release' //其中latest.release指代最新Bugly SDK版本号,也可以指定明确的版本号,例如2.2.0
}
<!-- 2.初始化,获取APP ID并将以下代码复制到项目Application类onCreate()中,Bugly会为自动检测环境并完成配置-->
CrashReport.initCrashReport(getApplicationContext(), "注册时申请的APPID", false);
有很多的sdk和系统的默认设置都会加到Application类或Activity类的onCreate()中,如第三方消息推送,这就导致onCreate()的逻辑较多,进而影响应用的启动、界面的加载都会有不同程度的影响,因此启动事件需要使用合适的方法进行度量。
4.1.3 代理工具:Activity启动事件+接口响应时间(第一个接口的发起时间和最后一个接口的响应完成时间)
- 1.使用adb查看Activity的启动事件
- 2.借助于Charles等抓包工具可以获取接口耗时 使用代理工具抓包,分析界面到底有多少个网络请求,每个网络请求的耗时
4.2 H5页面
可以使用chrome://inspect查看设备上H5页面的响应。
chrome部分版本取消了一个css标签的支持,导致页面混乱,此时可以下载版本62的chrome

1.根据版本号获取id https://omahaproxy.appspot.com/ 如62.0.3202.62的id为499098
2.替换id去下载chrome https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Mac/499098/
4.2.1 以浏览器模拟手机,页面如下

每个字段具体意义https://developers.google.com/devtools/docs/network#resource-network-timing
Request Table默认显示以下类目:
- Name 资源的名称
- Status HTTP状态码
- Type 已请求资源的MIME类型
- Initiator 发起请求的对象或进程。值为以下选项之一
* Parser Chrome的HTML解析器发起请求
* Redirect HTTP重定向发起请求
* Script 脚本发起请求
* Other 某些其他进程或操作发起请求,例如用户通过连接或者在地址栏输入网址导航到页面 - Size 响应标头(通常为数百字节)加响应正文(有服务器提供)的组合大小
- Time 从请求开始至响应中接收到最终字节的总持续时间
- Timeline 可以显示所有网络请求的可视瀑布。点击此列的标题可以显示一个包含更多字段的菜单。
4.2.2查看DOMContentLoaded和load事件信息

Network面板突出显示两种事件:DOMContentLoaded和load。
解析页面的初始标记时会触发DOMContentLoaded。此事件将在Network面板的两个地方显示
- Overview窗格中的蓝色竖线表示事件
- 在Summary窗格中,可以看到时间的确切时间
页面完全加载时将触发load。此事件显示在三个地方
1. Overview窗格中的红色竖线
2. Requests Table中的红色竖线也表示事件
3. 在Summary窗格中,可以看到事件的确切时间
ResourceTiming API提供了接受各个资源事件的有关的大量详细信息。
4.2.3 请求生命周期的主要阶段包括:

- 重定向
* 立即开始 startTime
* 如果正在发生重定向,redirectStart也会开始
* 如果重定向在本阶段未发生,将采集redirectEnd - 应用缓存
* 如果应用缓存在实现请求,将采集fetchStart时间 - DNS
- TCP
* connectStart 在初始连接到服务器时采集
* 如果正在使用TLS或SSL,secureConnectionStart将在握手(确保连接安全)开始时开始
* connectEnd将在服务器的连接完成时采集 - 请求
* requestStart 会在某个资源的请求被发送到服务器后立即采集 - 响应
* responseStart 是服务器初始响应请求的时间
* responseEnd 是请求结束并且数据完成检索的时间
如果有重定向,就进行重定向;如果没有重定向,就判断本地有没有cache。如果资源没有访问过,就查DNS,找网站。找到网站,与具体的网站建立连接,连接完成后,发起请求,服务端进行响应。此时界面仍然是空白的,直到DOMContentLoaded事件,load事件表明页面加载完成
4.2.4 Devtools中查看指定条目完整的耗时信息

- Queuing 如果某个请求正在排队,则指示:
* 请求已被选人引擎推迟,因为该请求的优先级被视为低于关键资源(例如脚本/样式)的优先级。图像经常大声这种情况。
* 请求已被暂停,以等待将要释放的不可用TCP套接字
* 请求已被暂停,因为在HTTP 1.0上,浏览器仅允许每个源拥有6个TCP连接
* 生成磁盘缓存条目所用的时间(通常非常迅速) - Stalled/Blocking 请求等待发送所用的时间。可以是等待Queuing中介绍的任何一个原因。此外,此时间包含代理协商所用的任何时间
- Proxy Negotiation 与代理服务器连接协商所用的时间。
- DNS Lookup 执行DNS查询所用的时间。页面上的每一个新域都需要完整的往返才能进行DNS查询。
- Initial Connection/Connecting 建立连接所用的时间,包括TCP握手/重试和协商SSL的时间
- SSL 完成SSL握手所用的时间
- Request Sent/Sending 发出网络请求所用的时间。通常不到1毫秒
- Waiting(TTFB 等待初始响应所用的时间,也称为第一字节的时间。此时间将捕捉到服务器往返的延迟时间,以及等待服务器传送响应所用的时间。谷歌建议至少在200毫秒以下
- Content Download/Downloading 接收响应数据所用的时间
4.2.5 webview开关
模拟器默认支持
针剂需要打开app内开关
//启用WebView调试,需要在WebView类上调用静态方法setWebContentsDebuggingEnabled
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
WebView.setWebContentsDebuggingEnabled(true);
}
9.2专项测试-Android性能测试黑盒分析-1的更多相关文章
- 移动App专项测试
移动App测试实战—专项测试 转自:http://www.51testing.com/html/58/n-3713758.html 我们在进行了手工的功能测试之后,也开发了一些自动化测试用例,并且做了 ...
- app专项测试
本节为大家讲述app的专项测试——客户端性能测试.这个我也做了蛮久的了.在这里修改了一下本篇随笔. 首先我们了解一下什么是客户端的性能测试.性能测试相比大家都已经耳熟能详了,这个app的客户端性能测试 ...
- 推荐支付宝 Android 专项测试工具SoloPi
推荐支付宝 Android 专项测试工具SoloPi 1 介绍 SoloPi是一个无线化.非侵入式的Android自动化工具,公测版拥有录制回放.性能测试.一机多控三项主要功能,能为测试开发人员节省宝 ...
- Android APP性能及专项测试
移动测试. Android测试 .APP测试 Android篇 1. 性能测试 Android性能测试分为两类:1.一类为rom版本(系统)的性能测试2.一类为应用app的性能测试 Android的a ...
- Android APP性能及专项测试(个人整理)
移动测试. Android测试 .APP测试 Android篇 1. 性能测试 Android性能测试分为两类:1.一类为rom版本(系统)的性能测试2.一类为应用app的性能测试 Android ...
- 专项测试-App性能分析
专项测试 app性能 Activity是Android组件中最基本也是最为常见用的四大组件(Activity,Service服务,Content Provider内容提供者,BroadcastRece ...
- Android专项测试监控资源
版本号 V 1.1.0 Android性能测试分为两类:1.一类为rom版本(系统)的性能测试2.一类为应用app的性能测试(本次主要关注点为app的性能测试) Android的app性能测试包括的测 ...
- Android性能测试 | 启动时间篇
[转载]原文地址:http://www.51testing.com/html/93/n-3724593.html 背景介绍 Android用户也许会经常碰到以下的问题: 1)应用后台开着,手机很快没电 ...
- 腾讯优测优分享 | Android性能测试工具化实现
腾讯优测专业的移动云测试平台,自动化测试提供性能测试数据,云真机实时输出性能数据,让测试更简单! 1.Android性能测试介绍 提到Android性能测试,我们总免不了俗地要首先介绍下Android ...
随机推荐
- 工作记录--WPF自定义控件,实现一个可设置编辑模式的TextBox
原文:工作记录--WPF自定义控件,实现一个可设置编辑模式的TextBox 1. 背景 因为最近在使用wpf开发桌面端应用,在查看页面需要把TextBox和Combox等控件设置为只读的.原本是个很简 ...
- js 获取指定字符串个数
参考:https://blog.csdn.net/maqinqin/article/details/5323824 function getStrCount(scrstr,armstr) { //sc ...
- js 仿微信投诉—引入vue.js,拆分组件为单个js
效果 页面目录 index.html <!DOCTYPE html > <html> <head> <meta charset="UTF-8&quo ...
- java自定义注解代码练习
/** * 自定义注解:校验非空字段 * */ @Documented @Inherited // 接口.类.枚举.注解 @Target(ElementType.FIELD) //只是在运行时通过反射 ...
- JS规则 我还有其它用途( +号操作符)例如,算术操作符(+、-、*、/等),比较操作符(<、>、>=、<=等),逻辑操作符(&&、||、!)
我还有其它用途( +号操作符) 操作符是用于在JavaScript中指定一定动作的符号. (1)操作符 看下面这段JavaScript代码. sum = numa + numb; 其中的"= ...
- 【颓废篇】人生苦短,我用python(一)
谁渴望来一场华(ang)丽(zang)的python交易! 最近突然产生了系统学习python的想法. 其实自从上次luogu冬日绘板dalao们都在写脚本就有这种想法了. 最近被计算几何势力干翻的我 ...
- 在双重for循环内部使用async异步请求axios中遇到的问题
在methods中的方法 async getPro () { let _this = this let newArr = [] await axios.get(`api/v1/dailyProTbms ...
- 廖雪峰Java11多线程编程-3高级concurrent包-2ReadWriteLock
ReentrantLock保证单一线程执行 ReentrantLock保证了只有一个线程可以执行临界区代码: 临界区代码:任何时候只有1个线程可以执行的代码块. 临界区指的是一个访问共用资源(例如:共 ...
- 17多校6 HDU - 6102
题意:给一个排列p,m次查询l,r,\(\sum_{i=l}^r\sum_{j=i+1}^r\sum_{k=j+1}^r[gcd(p_i,p_j)==p_k]p_k\) 题解:离线,枚举右端点,对于每 ...
- a common method to rotate the image
/* * clockwise rotate * first reverse up to down, then swap the symmetry * 1 2 3 7 8 9 7 4 1 * 4 5 6 ...
