## 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 崩溃分析

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面板的两个地方显示

  1. Overview窗格中的蓝色竖线表示事件
  2. 在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的更多相关文章

  1. 移动App专项测试

    移动App测试实战—专项测试 转自:http://www.51testing.com/html/58/n-3713758.html 我们在进行了手工的功能测试之后,也开发了一些自动化测试用例,并且做了 ...

  2. app专项测试

    本节为大家讲述app的专项测试——客户端性能测试.这个我也做了蛮久的了.在这里修改了一下本篇随笔. 首先我们了解一下什么是客户端的性能测试.性能测试相比大家都已经耳熟能详了,这个app的客户端性能测试 ...

  3. 推荐支付宝 Android 专项测试工具SoloPi

    推荐支付宝 Android 专项测试工具SoloPi 1 介绍 SoloPi是一个无线化.非侵入式的Android自动化工具,公测版拥有录制回放.性能测试.一机多控三项主要功能,能为测试开发人员节省宝 ...

  4. Android APP性能及专项测试

    移动测试. Android测试 .APP测试 Android篇 1. 性能测试 Android性能测试分为两类:1.一类为rom版本(系统)的性能测试2.一类为应用app的性能测试 Android的a ...

  5. Android APP性能及专项测试(个人整理)

    移动测试. Android测试 .APP测试   Android篇 1. 性能测试 Android性能测试分为两类:1.一类为rom版本(系统)的性能测试2.一类为应用app的性能测试 Android ...

  6. 专项测试-App性能分析

    专项测试 app性能 Activity是Android组件中最基本也是最为常见用的四大组件(Activity,Service服务,Content Provider内容提供者,BroadcastRece ...

  7. Android专项测试监控资源

    版本号 V 1.1.0 Android性能测试分为两类:1.一类为rom版本(系统)的性能测试2.一类为应用app的性能测试(本次主要关注点为app的性能测试) Android的app性能测试包括的测 ...

  8. Android性能测试 | 启动时间篇

    [转载]原文地址:http://www.51testing.com/html/93/n-3724593.html 背景介绍 Android用户也许会经常碰到以下的问题: 1)应用后台开着,手机很快没电 ...

  9. 腾讯优测优分享 | Android性能测试工具化实现

    腾讯优测专业的移动云测试平台,自动化测试提供性能测试数据,云真机实时输出性能数据,让测试更简单! 1.Android性能测试介绍 提到Android性能测试,我们总免不了俗地要首先介绍下Android ...

随机推荐

  1. 工作记录--WPF自定义控件,实现一个可设置编辑模式的TextBox

    原文:工作记录--WPF自定义控件,实现一个可设置编辑模式的TextBox 1. 背景 因为最近在使用wpf开发桌面端应用,在查看页面需要把TextBox和Combox等控件设置为只读的.原本是个很简 ...

  2. js 获取指定字符串个数

    参考:https://blog.csdn.net/maqinqin/article/details/5323824 function getStrCount(scrstr,armstr) { //sc ...

  3. js 仿微信投诉—引入vue.js,拆分组件为单个js

    效果 页面目录 index.html <!DOCTYPE html > <html> <head> <meta charset="UTF-8&quo ...

  4. java自定义注解代码练习

    /** * 自定义注解:校验非空字段 * */ @Documented @Inherited // 接口.类.枚举.注解 @Target(ElementType.FIELD) //只是在运行时通过反射 ...

  5. JS规则 我还有其它用途( +号操作符)例如,算术操作符(+、-、*、/等),比较操作符(<、>、>=、<=等),逻辑操作符(&&、||、!)

    我还有其它用途( +号操作符) 操作符是用于在JavaScript中指定一定动作的符号. (1)操作符 看下面这段JavaScript代码. sum = numa + numb; 其中的"= ...

  6. 【颓废篇】人生苦短,我用python(一)

    谁渴望来一场华(ang)丽(zang)的python交易! 最近突然产生了系统学习python的想法. 其实自从上次luogu冬日绘板dalao们都在写脚本就有这种想法了. 最近被计算几何势力干翻的我 ...

  7. 在双重for循环内部使用async异步请求axios中遇到的问题

    在methods中的方法 async getPro () { let _this = this let newArr = [] await axios.get(`api/v1/dailyProTbms ...

  8. 廖雪峰Java11多线程编程-3高级concurrent包-2ReadWriteLock

    ReentrantLock保证单一线程执行 ReentrantLock保证了只有一个线程可以执行临界区代码: 临界区代码:任何时候只有1个线程可以执行的代码块. 临界区指的是一个访问共用资源(例如:共 ...

  9. 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\) 题解:离线,枚举右端点,对于每 ...

  10. 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 ...