APP自动化测试

时间:2022-01-14 18:36:11

测试环境一般用真机,有一套系统,搭载在服务器上,很多usb出来,连接各手机进行测试。这里我们用模拟器进行讲解(安卓Linux,IOSUnix)

目录:

一、ADB

二、Monkey

三、Monkey Script

四、MonkeyRunner

五、监控分析专项

一、ADB

安装好模拟器,配置好环境变量啥的(已经在之前的博客内有介绍)

1、安装JDK
2、安装Android SDK(可以在这里下载:http://www.android-studio.org/)
3、配置环境变量:

ANDROID_HOME=.../sdk
PATH=%ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools;%ANDROID_HOME%\build-tools\android-4.4.2;

APP自动化测试

 


注意:JDK和SDK的位数必须一致。

 

介绍两个小工具:

1、百度:测试助手(简单)
2、腾讯:GT(详细)

测试助手:

APP自动化测试

结果:APP自动化测试

 内存泄漏:

内存一直升/GC回收之后,内存未降到底

APP自动化测试

 

 adb命令(Android debug bridge-安卓调试桥-相当于USB线):

APP自动化测试

192.168.238.101.5555 是deviceid

出现这个情况,就可以直接用命令了:

1.adb help

2.adb devices 取得当前运行的模拟器/设备的实例的列表及每个实例的状态

3.adb install gzw.apk 安装应用程序(直接跟apk的路径以及文件名即可)

4.adb -s 123 install zw.apk 给指定的设备安装apk(123指的是deviceid)

5.adb pull <remote> <local> 从远程到本地,从手机下载文件到电脑(可以加-s 123 指定模拟器的id;remote/local是指的是路径)

6.adb push <local> <remote> 从本地到远程,从电脑上传文件到手机(可以加-s 123 指定模拟器的id;remote/local是指的是路径

7.adb start-server 启动服务(可以加-s 123 指定模拟器的id)

8.adb kill-server 杀死服务(可以加-s 123 指定模拟器的id)

9.adb shell 必须是root才行 进入linux

10.adb logcat 日志(可以加-s 123 指定模拟器的id)

 关于adb logcat:

APP自动化测试

优先级从低到高排列
 V-Verbose(lowest priority)
 D-Debug
 I-Info
 W-Warning
 E-Error
 F-Fatal
 S-Silent(highest priority,on which nothing is ever printed)
下面的过滤语句只显示优先级为warning或更高的日志信息
adb logcat *:W(意思是显示W、E、F、S级别的日志)

 

二、Monkey

1、概念

monkey,是个啥?什么时候用呢?为什么要用monkey呢?

monkey=猴子,相当于是个猴子在操作你的手机,咔咔咔这里点那里点,随机操控app的工具,测试app是否稳定,关键在于测试稳定性。

运行时机:一般是产品稳定后,首轮功能测试完成后的夜间进行。测试稳定性,一般要改完一轮Bug之后。需要知道PackageName

为什么用?主要用来测试产品是否存在崩溃问题以及ANR(applicatuion no response)问题

2、获取PackageName

1、aapt
  aapt dump badging apk名称

前提:aapt.exe要在环境变量路径下:

APP自动化测试

命令:aapt dump badging apk名称(apk名称为apk在电脑里面的路径以及名称)

比如:aapt dump badging F:\BaiduNetdiskDownload\软件\iBiliPlayer-bili.apk

PackageName:

APP自动化测试

ActivityName:

APP自动化测试

 

 


2、通过adb logcat获取
  adb logcat | grep START  ##这个是不行的,原因在于,grep是linux命令,| grep START认为是在window内操作的,所以会报错

APP自动化测试

 

  所以, 用下面的语句:
  adb shell “logcat | grep START”

APP自动化测试

 在这个情况下,拉到底,然后去模拟器内打开你需要打开的APP,在cmd内查看日志变化:

我们可以发现,多了了一个cmp=tv.danmaku.bili/.ui.splash.SplashActivity……

tv.danmaku.bili是PackageName

tv.danmaku.bili.ui.splash.SplashActivity是ActivityName

比如说:计算器的PackageName为:com.android.calculator2

ActivityName为.Calculator

APP自动化测试

 3、Monkey的基本命令

APP自动化测试

 

1、标准monkey命令:

adb shell monkey -p com.android.calculator2 -v 50

-p:packageName(这里用的是com.android.calculator2

-v:日志级别

-v -v代表不认同的日志级别

-v -v -v代表不认同的日志级别

50:事件数

结果:对计算器进行了100次事件,但是是在计算其内部进行100次事件:

APP自动化测试

那些2:2.0%一直到10:13%指的是时间的类型比例,比如说:点击、滑动、轨迹球事件等
2、

adb shell monkey -p com.android.calculator2 -v -v --pct-touch 50 --throttle 600 88

--pct-touch 50 设置整个过程中点击操作所占的百分比

--throttle 600 每个事件间隔600ms

88 意思是 88个事件数

这样执行,每个事件中间有延时,可以看清操作

APP自动化测试
3、实际工作中营的命令,这里的packagename要更换,1000000的动作记得换掉,如果要执行一晚上一般设置100万,时间间隔500ms是为了防止动作太快导致异常;这些错误啥的都会忽略,不忽略会停止,但是执行的日只会存在文件内。ANR是无响应,操作太快容易出现ANR

adb shell monkey -p packagename --throttle 500 --ignore-crashes --ignore-timeouts --ignore-security-exceptions --ignore-native-crashes --monitor-native-crashes -v -v -v 1000000 > c:\monkey_test.log

4、关于日志级别

参数: -v
  用于指定反馈信息级别(信息级别就是日志的详细程度),总共分3个级别,分别对应的参数如下表所示:
1、日志级别 Level0
  示例 adb shellmonkey -p com.htc.Weather –v 100
  说明 缺省值,仅提供启动提示、测试完成和最终结果等少量信息
2、日志级别 Level 1
  示例 adb shellmonkey -p com.htc.Weather –v -v 100
  说明 提供较为详细的日志,包括每个发送到Activity的事件信息
3、日志级别 Level 2
  示例 adb shellmonkey -p com.htc.Weather –v -v –v 100
  说明 最详细的日志,包括了测试中选中/未选中的Activity信息

5、Monkey的事件类型

  1. pct-touch:指定触摸事件的百分比,如:--pct-touch 5
  2. pct-motion <percent> (滑动事件)
  3. pct-trackball <percent> (轨迹球事件)
  4. pct-nav <percent> (导航事件 up/down/left/right)
  5. pct-majornav <percent> (主要导航事件 back key 、 menu key)
  6. pct-syskeys <percent> (系统按键事件 Home 、Back 、startCall 、 endCall 、 volumeControl)
  7. pct-appswitch <percent> (activity之间的切换)
  8. pct-anyevent <percent>(任意事件)

6、Monkey的参数 -s

参数: -s
用于指定伪随机数生成器的seed值,如果seed相同,则两次Monkey测试所产生的事件序列也相同的。
示例:
Monkey测试1:adb shell monkey -p com.htc.Weather –s 10 100
Monkey 测试2:adb shell monkey -p com.htc.Weather–s 10 100
两次测试的效果是相同的,因为模拟的用户操作序列(每次操作按照一定的先后顺序所组成的一系列操作,即一个序列)是一样的。操作序列虽然是随机生成的,但是只要我们指定了相同的Seed值,就可以保证两次测试产生的随机操作序列是完全相同的,所以这个操作序列伪随机的;

adb shell monkey -p com.android.calculator2 -s 10 -v -v -v 100 >c:monkey_test1.log

这里我们看到输出的日志,seed值都为10,seed是用来复现以及回归问题的;因为假设不用seed,你不知道问题出在哪,开发说解决了,你也不知道怎么回归,有了这个seed值,咱们就可以进行一模一样的操作,seed值可以跟日志编号对上,这样更直观;但是两次执行初始状态要一致,比如清空计算器内容。

这样有两种方式:1、第一次就指定 -s 的seed值;2、出现问题后,第二次执行找到第一次有问题的seed值,再执行

APP自动化测试

 

7、Monkey的其他参数

  1. --ignore-crashes 用于指定当应用程序崩溃时(Force& Close错误),Monkey是否停止运行。如果使用此参数,即使应用程序崩溃,Monkey依然会发送事件,直到事件计数完成。
  2. --ignore-timeouts 用于指定当应用程序发生ANR(Application No Responding)错误时,Monkey是否停止运行。如果使用此参数,即使应用程序发生ANR错误,Monkey依然会发送事件,直到事件计数完成。
  3. --ignore-security-exceptions 用于指定当应用程序发生许可错误时(如证书许可,网络许可等),Monkey是否停止运行。如果使用此参数,即使应用程序发生许可错误Monkey依然会发送事件,直到事件计数完成。
  4. --kill-process-after-error 用于指定当应用程序发生错误时,是否停止其运行。如果指定此参数,当应用程序发生错误时,应用程序停止运行并保持在当前状态(注意:应用程序仅是静止在发生错误时的状态,系统并不会结束该应用程序的进程)。
  5.  --monitor-native-crashes 用于指定是否监视并报告应用程序发生崩溃的本地代码

 

APP自动化测试

 8、Monkey的日志分析

  1. 按关键字进行搜索,ANR、Exception、Crash、Error。(有Crash一般有Exception)
  2. 找到有问题的地方,查看上下文信息。
  3. 注意第一个switch上下文信息
  4. 查看monkey里面出错前的一些事件动作,可以手动执行该动作。
  5. 进行问题复现,可以使用之前执行的monkey命令在执行一遍,注意seed值要一样

APP自动化测试

9、Crash专项

  1. 安装可以引起Crash的App
  2. 执行压力命令
  3. 析取Crash的Exception信息

资料里面有这个引起Crash的apk,我们如果以后出现Crash的错误,怎没去析取呢?

adb shell monkey -p cn.besttest.crashtest -v -v -v 1000 > c:\monkey_test3.log

首先可以在日志里面看一下时间数,我们这里是963<1000,说明有些事件没完成(Crash是停止运行,ANR是无响应)

APP自动化测试

提示堆栈信息,截图给开发就行

APP自动化测试

 那么假如我们忽略Crash呢?

adb shell monkey -p cn.besttest.crashtest --ignore-crashes -v -v -v 1000 > c:\monkey_test4.log

 忽略了Crash,就算触发了Crash之后,monkey会把app杀死重新打开再操作,所以日志内的事件数依旧为1000

APP自动化测试

但是日志内,依旧有Crash操作被记录下来:

APP自动化测试

10、ANR专项

  1. 安装可以引起ANR的App
  2. 执行压力命令
  3. 析取ANR的Exception信息

 

  1. 查看monkey的log
  2. /data/anr/traces.txt
  3. 查看logcat日志 ANR

同样的,安装引起ANR的apk

输入命令:

adb shell monkey -p cn.besttest.anrtest -v -v -v 1000 > c:\monkey_test_anr1.log

ANR是操作无响应

APP自动化测试

在/data/anr/traces.txt目录下,我们可以拉取出来看一下,把这个文件以及log问阿金给开发就成

APP自动化测试

 三、Monkey Script

好处:可以规定干什么

  •  MonkeyScript是一组可以被Monkey识别的命令集合
  •  优点:MonkeyScript可以完成重复固定的操作
  •  使用:adb shell monkey -f <scriptfile> <event-count>(scriptfile指的是脚本;event-Count是事件数)

1、Monkey Script命令

1、DispatchTrackball-轨迹球事件

DispatchTrackball(long downtime,long eventtide,int action,float x,float y,float pressure,float size,int metastate,float xprecision,float yprecision,int device,int edgeflags)

  注意:按一个键需要两个轨迹球事件

DispatchTrackball参数详解

  • long downtime    指键最初被按下的时间
  • long eventtide    指事件发生的时间
  • int action    指具体操作的动作,如按下
  • float x,float y    指x和y的坐标
  • float pressure    压力事件的大小(0~1)
  • float size    指触摸的记事值(0~1)
  • int metastate    指当前按下mate键的标识
  • float xprecision,float yprecision    指x和y坐标的精确值
  • int device    事件的来源(0~x)
  • int edgeflags    指超出屏幕了范围
  • int action    0代表按下,1代表弹起

2、DispatchPointer-点击事件

DispatchPointer(long downtime,long eventtide,int action,float x,float y,float pressure,float size,int metastate,float xprecision,float yprecision,int device,int edgeflags)

注意:按一个键需要两个点击事件

  参数详解见轨迹球事件

3、DispatchString-输入字符串命令

  DispatchString(String text)

4、LaunchActivity-启动应用

  LaunchActivity(package,Activity)

5、UserWait-等待事件(单位:ms)

  UserWait(1000)

6、DispatchPress-按下键值(键值

  DispatchPress(int keycode)

  #keycode 66 回车键

 2、Monkey Script 实战

  在浏览器的百度搜索框中输入查询词“besttest”并得出搜索结果

解答:要哪几步操作才能完成操作?

  1. 启动App
  2. 点击地址栏
  3. 删除原有地址
  4. 输入www.baidu.com
  5. 点击回车键,让新地址到地址栏中
  6. 点击回车
  7. 点击搜索框
  8. 输入besttest
  9. 点击回车键,让查询词到搜索框中
  10. 点击搜索按钮
  11. 等待结果
typ=user
count=10
speed=1.0
start data >>

LaunchActivity(com.android.browser,com.android.browser.BrowserActivity)
UserWait(5000)
DispatchPointer(10,10,0,256,100,1,1,-1,1,1,0,0)
DispatchPointer(10,10,1,256,100,1,1,-1,1,1,0,0)
DispatchPress(112)
DispatchString(www.baidu.com)
DispatchPress(66)
UserWait(10000)
DispatchPointer(10,10,0,125,500,1,1,-1,1,1,0,0)
DispatchPointer(10,10,1,125,500,1,1,-1,1,1,0,0)
UserWait(1000)
DispatchString(besttest)
UserWait(3000)
DispatchPress(66)
UserWait(10000)

   注:前四行是必须要有的

 

写好了脚本之后,要把脚本拉取到移动端内执行:

APP自动化测试

接下来可以在adb shell内运行monkey,结果如图:

APP自动化测试

 

或者退出adb shell 用 adb shell monkey -f <scriptfile> <event-count> 运行,结果是一致的:

APP自动化测试

 

MonkeyScript注意

  脚本需要push到手机中才可以
  push monkey.script /data/local/tmp
  没有调试的功能,需要自己仔细去找问题
  如果启动时并不是自己要测试的App,需要开发在Android的配置文件中加入相关配置
  android:exported=”true”

APP自动化测试

 

四、MonkeyRunner

  • MonkeyRunner提供了系列的API
  • MonkeyRunner可以完成模拟事件及截图操作

分为三块:

  1. MonkeyRunner:用来连接设备或模拟器的
  2. MonkeyDevice:提供安装、卸载应用,发送模拟事件
  3. MonkeyImage:完成图像保存及对比的操作

可以用来干什么?

  • 多设备控制
  • 功能测试
  • 回归测试

1、MonkeyRunnerAPI

1、alert

  警告框

MonkeyRunner.alert(string message, string title, string okTitle)

  message: 弹出对话框内容
  title: 对话框的标题栏显示内容,默认值为"Alert"
  okTitle : 对话框的按钮,默认值为"OK"

  试一下:首先要进入monkeyrunner,再敲命令,要退出这个命令按“Ctrl+d

APP自动化测试

 

2、waitForConnection

  等待设备连接,多个设备,需要指明哪个设备

MonkeyRunner.waitForConnection(float timeout, string deviceId)

  timeout: 等待超时时间,默认值为永久等待.
  deviceId: 通过设备ID去设别手机或模拟器.如果只有一台手机的时候,不需要输入

2、MonkeyDeviceAPI

1、drag

  拖动

device.drag(tuple start, tuple end, float duration, integer steps)

  (1,2) (3,4)
  start:起始点位置
  end:终点位置
  duration:手势持续的时间
  steps:插值点的步数,默认10

2、press

  按键

device.press(string keycode,dictionary type)

  type:DOWN、UP、DOWN_AND_UP

3、startActivity

  启动应用

device.startActivity(package+'/'+activity)

4、touch

  点击

device.touch(int x,int y,type)

  type:DOWN、UP、DOWN_AND_UP

5、type

  输入

device.type(string message)

6、takeSnapshot

  截屏

device.takeSnapshot()

 

3、MonkeyImageAPI

1、sameAs

  图像对比

picture.sameAs(MonkeyImage other,float percent)

  percent:对比相似度

2、writetoFile

  保存图像文件

picture.writeToFile(string path,string format)

  string path,存储全路径,包括文件扩展名。

  string format,存储格式

4、实例

 还是刚刚那个例子,但是最后加一步截屏保存在本地

首先要知道所连接设备的端口号:192.168.238.101:5555

APP自动化测试

 

脚本如下(脚本为.py文件):

 

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage
device = MonkeyRunner.waitForConnection(5,"192.168.238.101:5555")
device.startActivity("com.android.browser/.BrowserActivity")
MonkeyRunner.sleep(5)
device.touch(200,100,'DOWN_AND_UP')
MonkeyRunner.sleep(1)
device.press('KEYCODE_FORWARD_DEL','DOWN_AND_UP')
device.type('www.baidu.com')
device.press('KEYCODE_ENTER','DOWN_AND_UP')
MonkeyRunner.sleep(10)
device.touch(150,500,'DOWN_AND_UP')
MonkeyRunner.sleep(1)
device.type('besttest')
MonkeyRunner.sleep(3)
device.press('KEYCODE_ENTER','DOWN_AND_UP')
MonkeyRunner.sleep(10)
image=device.takeSnapshot()
image.writeToFile('C:\\monkeyrunnerscript1.png','png')
MonkeyRunner.sleep(3)

注意:这里我们引用的而路径要为绝对路径:monkeyrunner c:\XXX.py

这是为什么呢?因为相对路径相对的是monkeyrunner.exe所在的位置是相对位置,而我们是放在C盘内的

APP自动化测试

 

 

Monkey和MonkeyRunner的区别

  • Monkey:在adb shell中,生成用户或系统的伪随机事件
  • MonkeyRunner:通过API定义特定命令和事件控制设备

MonkeyRunner没有事件数,MonkeyScript有事件数,相对来说,MonkeyRunner相对灵活,可以用Python语言。工作中,自动化测试基于坐标不是最优解决方案,最重要的是 Monkey ,其他的都不是很重要

 

五、监控分析专项

  1. 启动App。
  2. DDMS->update heap
  3. 操作app,点几次GC
  4. dump heap
  5. hprof-conv转化
  6. MAT分析

app 内存泄漏的案例:

准备工作:安装 MyMemoryDemo 的 apk ,电脑上装好 mat

APP自动化测试

这里我们不用 DDMS ,而是用功能更强大的 monitor 在 cmd 下输入 monitor(前提是要配置好环境变量),电脑会自动打开 Android Debug Monitor :

APP自动化测试

 

有些功能简单介绍:

1、截取手机当前屏幕

APP自动化测试

2、页面元素定位,Appium 做前端自动化,要用到这个

APP自动化测试

3、利用 Logcat 筛选日志:

APP自动化测试

保存好的过滤结果:

APP自动化测试

 

我们的案例主要讲内存的泄漏,重点关注 Heap,操作如下:

1、先打开 app:

APP自动化测试

 

 2、选中我们 app 对应的 package,点击 "Update Heap",点击 "Cause GC",等到数据加载完成

APP自动化测试

3、操作 app ,点击“点我啊点我啊”,一次点击一下,别乱点,别超过10次

APP自动化测试

我们要关注的是 "data object" 内 的 "Total Size",如果我们点 app 的按钮,如果该值一直增加,我们点击 "Cause GC",该值不会减少或者说减小的幅度很小,那么说明存在内存泄漏

APP自动化测试

我们看看看结果:

APP自动化测试

 把内存 dump 下来一份,路径:D:\adt-bundle-windows-x86_64-20140321\adt-bundle-windows-x86_64-20140321\sdk\tools\111,直接保存就好了。

dump 完 monitor 关闭就行

APP自动化测试

4、hprop-conv 转化,转化的命令如代码所示,转化后的文件不要跟之前的一样,这里我用的是 cn.besttest.mymemorydemobak.hprof

C:\Users\Admin>d:

D:\>cd D:\adt-bundle-windows-x86_64-20140321\adt-bundle-windows-x86_64-20140321\sdk\tools\111

D:\adt-bundle-windows-x86_64-20140321\adt-bundle-windows-x86_64-20140321\sdk\tools\111>hprof-conv cn.besttest.mymemorydemo.hprof cn.besttest.mymemorydemobak.hprof

 

在路径下,应该会多出一个文件:

APP自动化测试

 

5、打开 mat ,对转化后的文件进行分析,出现提示直接点 "Finish":

APP自动化测试

直接看大对象,我们通常都看第一个 java.lang Object[] 数组,这个是我们程序创建的对象:Shallow Heap 是自己本身占用的内存,Retained Heap 还包括引用的内存

APP自动化测试

选中 java.lang Object[],右键

APP自动化测试

 

 接下来,继续选中第一个,右键:

APP自动化测试

结果如图:

出现内存泄漏的点在于:我有一个 list ,而且这个 list 是一个 array 的 list ,这个 list 内的对象装的是 cn.besttest.mymemorydemo 里面的 BestTest ,其实代码里面确实是如此,BestTest 类产生的对象往一个 array list 内放,制空只是把对象制空,并没有把 list 制空,导致内存一直无法释放,这就是内存泄漏的原因

APP自动化测试

 

1、区分几种内存

  • VSS- Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
  • RSS- Resident Set Size 实际使用物理内存(包含共享库占用的内存)
  • PSS- Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
  • USS- Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)

一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS

监控首选 PSS ,如果没有 PSS ,那就看 RSS

2、监控-内存

一、通过Dumpsys 来取值

  • adb shell dumpsys meminfo
  • 详细信息:adb shell dumpsys meminfo pakagename or Pid

例如,我们看下 b站 的内存占用情况

C:\Users\Admin>adb shell dumpsys meminfo tv.danmaku.bili
Applications Memory Usage (kB):
Uptime: 1770422 Realtime: 1770422

** MEMINFO in pid 1316 [tv.danmaku.bili] ** Pss  Private  Private  Swapped     Heap Heap Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap     9370     9340        0        0    15992    14176      847
  Dalvik Heap     9774     9712        0        0    15644     9452     6192
 Dalvik Other     5475     5348        0        0
        Stack      412      412        0        0
       Ashmem     3668     3668        0        0
    Other dev        8        0        8        0
     .so mmap     3247      708      672        0
    .apk mmap      776        0      460        0
    .ttf mmap     1168        0      720        0
    .dex mmap     7337     1280     2944        0
   Other mmap       44        4        4        0
      Unknown      244      244        0        0
        TOTAL    41523    30716     4808        0    31636    23628     7039

 Objects
               Views:      287         ViewRootImpl:        1
         AppContexts:        3           Activities:        1
              Assets:        3        AssetManagers:        3
       Local Binders:       27        Proxy Binders:       23
    Death Recipients:        0
     OpenSSL Sockets:        5

 SQL
         MEMORY_USED:      536
  PAGECACHE_OVERFLOW:      110          MALLOC_SIZE:       62

 DATABASES
      pgsz     dbsz   Lookaside(b)          cache  Dbname
         4       16            123         9/20/6  /data/data/tv.danmaku.bili/databases/evernote_jobs.db
         4       40             64       16/35/11  /data/data/tv.danmaku.bili/databases/tencent_analysis.db_tv.danmaku.bili
         4       40             43        10/25/7  /data/data/tv.danmaku.bili/databases/pri_tencent_analysis.db_tv.danmaku.bili
         4       52            144       51/32/18  /data/data/tv.danmaku.bili/databases/bugly_db_
         4       28             32         1/16/2  /data/data/tv.danmaku.bili/databases/unicom.db

 

 

我们要关注的就是:PSS 那一列以及Dalvik Heap 那一行 ,行有 Native Heap 和 Dalvik Heap 分别是:本地内存,Dalvik Heap 理解为 Java 堆内存。Heap Size 就是堆内存总共大小,Heap Alloc 就是使用了多少,Heap Free 就是空闲了多少,通常来讲:Alloc+Free≈Size。

二、用/system/xbin/procrank工具 来取值很直观

  • adb shell procrank
C:\Users\Admin>adb shell procrank
  PID       Vss      Rss      Pss      Uss  cmdline
 1316   669004K  100300K   57039K   50464K  tv.danmaku.bili
  656   608348K   73200K   36666K   33108K  com.android.systemui
  828   598960K   58500K   21985K   18168K  com.android.launcher
  571   656748K   60900K   21861K   17364K  system_server
  225    77056K   24064K   17524K   14508K  /system/bin/mediaserver
  223   553436K   57596K   14812K    7320K  zygote
 1723   595072K   48832K   10099K    5856K  tv.danmaku.bili:download
……------   ------  ------ 287994K 221172K TOTAL

RAM: 2068968K total, 1584364K free, 8020K buffers, 230420K cached, 9928K shmem, 22820K slab


C:\Users\Admin>adb shell " procrank | grep tv.danmaku.bili "  ## 看 b站 包的内存使用情况
 1316   700552K  132196K   88959K   82368K  tv.danmaku.bili
 1723   595072K   48832K   10121K    5856K  tv.danmaku.bili:download
 1692   595392K   48088K    9763K    5700K  tv.danmaku.bili:stats
 1364   583192K   43364K    8764K    5896K  tv.danmaku.bili:pushservice

 

 这里,我们看 PSS 这一列就成,同样可以去利用这个,打点制图,取出监控数据

三、top

  • top -d 1 | grep packageName
  • adb shell top -d 1 | grep packageName
C:\Users\Admin>adb shell top  ## 看整体的内存消耗

User 0%, System 0%, IOW 0%, IRQ 0%
User 0 + Nice 0 + Sys 6 + Idle 1143 + IOW 0 + IRQ 0 + SIRQ 3 = 1152

  PID PR CPU% S  #THR     VSS     RSS PCY UID      Name
 1316  3   0% S    50 679964K 109572K  fg u0_a60   tv.danmaku.bili
  213  0   0% S    14  68032K   7552K     root     /system/bin/local_opengl
  571  1   0% S    69 656752K  58972K  fg system   system_server
  609  2   0% S    11  52120K   3436K  fg system   /system/bin/surfaceflinger
    8  2   0% S     1      0K      0K     root     rcu_preempt
 2062  0   0% R     1   1908K    504K     root     top
    9  0   0% S     1      0K      0K     root     rcu_bh
   10  0   0% S     1      0K      0K     root     rcu_sched

……

 

 

 上述命令,可以看到整体的内存使用,如果我们要看单个的应用内存使用,就应该用下面的:

 C:\Users\Admin>adb shell "top | grep tv.danmaku.bili"  ## tv.danmaku.bili:pushservice 是我们不需要的,重点看 tv.danmaku.bili
 1316  2   0% S    50 686768K 116224K  fg u0_a60   tv.danmaku.bili
 1364  1   0% S    13 584236K  43052K  fg u0_a60   tv.danmaku.bili:pushservice
 1692  0   0% S    22 595396K  47352K  bg u0_a60   tv.danmaku.bili:stats
 1723  1   0% S    22 595076K  48200K  bg u0_a60   tv.danmaku.bili:download
 1316  2   0% S    50 686900K 116224K  fg u0_a60   tv.danmaku.bili
 1364  1   0% S    13 584236K  43052K  fg u0_a60   tv.danmaku.bili:pushservice
 1692  0   0% S    22 595396K  47352K  bg u0_a60   tv.danmaku.bili:stats
 1723  1   0% S    22 595076K  48200K  bg u0_a60   tv.danmaku.bili:download
 1316  2   0% S    50 686900K 116488K  fg u0_a60   tv.danmaku.bili
 1364  1   0% S    13 584236K  43052K  fg u0_a60   tv.danmaku.bili:pushservice
 1692  0   0% S    22 595396K  47352K  bg u0_a60   tv.danmaku.bili:stats
 1723  1   0% S    22 595076K  48200K  bg u0_a60   tv.danmaku.bili:download
……

C:\Users\Admin>adb shell "top | grep tv.danmaku.bili$"  ## 加一个正则,表示以 tv.danmaku.bili 结尾的行打印出来,所以我们达到了效果
 1316  0   0% S    50 692504K 121988K  fg u0_a60   tv.danmaku.bili
 1316  2   0% S    50 692504K 121988K  fg u0_a60   tv.danmaku.bili
 1316  3   0% S    50 692636K 121988K  fg u0_a60   tv.danmaku.bili
 1316  3   0% S    50 692636K 121988K  fg u0_a60   tv.danmaku.bili
 1316  0   0% S    50 692768K 122252K  fg u0_a60   tv.danmaku.bili
……


C:\Users\Admin>adb shell "top -d 1 | grep tv.danmaku.bili$"  ## -d 1 的意思是,每隔一秒显示一次,把数据取出来,打点制图,就知道了内存的使用情况
 1316  3   0% S    50 694880K 124364K  fg u0_a60   tv.danmaku.bili
 1316  1   0% S    50 694880K 124364K  fg u0_a60   tv.danmaku.bili
 1316  1   0% S    50 694880K 124364K  fg u0_a60   tv.danmaku.bili
 1316  2   0% S    50 694880K 124364K  fg u0_a60   tv.danmaku.bili
 1316  2   0% S    50 695012K 124364K  fg u0_a60   tv.danmaku.bili
 1316  2   0% S    50 695012K 124364K  fg u0_a60   tv.danmaku.bili
 1316  1   0% S    50 695012K 124628K  fg u0_a60   tv.danmaku.bili
 1316  1   0% S    50 695012K 124628K  fg u0_a60   tv.danmaku.bili

 

之前我们说过看 PSS ,没有 PSS 就看 RSS ,这里只有 RSS 可以看。Name 就是 PackageName,PID 就是应用的 pid,CPU% 就是 CPU 使用率,同样的可以打点制图,得出内存的使用趋势

3、关于单个应用内存占用量问题

#查看单个应用程序最大内存限制
  adb shell getprop|grep heapgrowthlimit
#应用启动后分配的初始内存
  adb shell getprop|grep dalvik.vm.heapstartsize
#单个java虚拟机最大的内存限制
  adb shell getprop|grep dalvik.vm.heapsize

C:\Users\Admin>adb shell "getprop|grep heapgrowthlimit"
[dalvik.vm.heapgrowthlimit]: [96m]

C:\Users\Admin>adb shell "getprop|grep dalvik.vm.heapstartsize"
[dalvik.vm.heapstartsize]: [8m]

C:\Users\Admin>adb shell "getprop|grep dalvik.vm.heapsize"
[dalvik.vm.heapsize]: [256m]

 

应用程序默认达到 heapgrowthlimit 限制的内存,就会爆出 OOM ,堆内存溢出
应用程序如果不想在 dalvik heap 达到 heapgrowthlimit 限制的时候出现OOM,需要在 Manifest 中的 application 标签中声明 android:largeHeap=“true”,声明后应用 dalvik heap 达到 heapsize 的时候才会出现OOM!
注:设备的不一样 最大内存限制也可能不一样

4、监控-CPU

一、通过Dumpsys 来取值

  • adb shell dumpsys cpuinfo
C:\Users\Admin>adb shell dumpsys cpuinfo
Load: 0.04 / 0.05 / 0.05
CPU usage from 16143ms to 4679ms ago:
  1.2% 213/local_opengl: 0% user + 1.2% kernel
  1% 1316/tv.danmaku.bili: 0.6% user + 0.3% kernel / faults: 64 minor
  0.8% 609/surfaceflinger: 0.1% user + 0.6% kernel
  0.5% 571/system_server: 0% user + 0.4% kernel
  0.1% 84/redis: 0% user + 0.1% kernel
  0% 8/rcu_preempt: 0% user + 0% kernel
  0% 782/com.android.phone: 0% user + 0% kernel
0.7% TOTAL: 0.2% user + 0.4% kernel + 0% softirq

 

这里后面也可以加入 grep 到自己的 packagename,得到 cpu 的使用率,上述可以看到,1% 的 cpu 使用率,1316 为 进程 pid 号,用户态为 0.6%,内核态为 0.3%

二、top

  • top -d 1 | grep packageName
C:\Users\Admin>adb shell "top -d 1 | grep tv.danmaku.bili$"
 PID PR CPU% S  #THR     VSS     RSS PCY UID      Name
1316 2 0% S 50 736592K 166392K fg u0_a60 tv.danmaku.bili 1316 0 0% S 50 736592K 166392K fg u0_a60 tv.danmaku.bili 1316 0 0% S 50 736592K 166392K fg u0_a60 tv.danmaku.bili 1316 0 0% S 50 736724K 166392K fg u0_a60 tv.danmaku.bili

 

CPU% 就是 cpu 使用率

5、查看PID/UID

pid:

通过ps命令查看pid
  ps | grep packageName

C:\Users\Admin>adb shell " ps |grep tv.danmaku.bili"
u0_a60    1316  223   753032 182776 ffffffff b766c07b S tv.danmaku.bili
u0_a60    1364  223   584236 42760 ffffffff b766c07b S tv.danmaku.bili:pushservice
u0_a60    1692  223   595396 47352 ffffffff b766c07b S tv.danmaku.bili:stats
u0_a60    1723  223   595076 48200 ffffffff b766c07b S tv.danmaku.bili:download

 

uid:

一、通过查看packages.list
  adb shell cat /data/system/packages.list | grep packageName
二、查看status文件
  adb shell cat /proc/<pid>/status
此处的<pid>需要替换成自己的pid的值

C:\Users\Admin>adb shell "cat /data/system/packages.list | grep tv.danmaku.bili"  ## 这里面的 10060 就是 uid
tv.danmaku.bili 10060 0 /data/data/tv.danmaku.bili default 1028,3003,1015


C:\Users\Admin>adb shell cat /proc/1316/status  ## 1316 是 b站 的 pid,Uid 就是我们要的,这里是 10060 ,和上面的一致
Name:   tv.danmaku.bili
State:  S (sleeping)
Tgid:   1316
Pid:    1316
PPid:   223
TracerPid:      0
Uid:    10060   10060   10060   10060
Gid:    10060   10060   10060   10060
FDSize: 256
Groups: 1015 1028 3003 50060
VmPeak:   756624 kB
VmSize:   755468 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:    184952 kB
VmRSS:    184952 kB
VmData:   177628 kB
VmStk:       136 kB
VmExe:         8 kB
VmLib:     89148 kB
VmPTE:       372 kB
VmSwap:        0 kB
Threads:        50
SigQ:   0/16154
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000001204
SigIgn: 0000000000000000
SigCgt: 00000002000094f8
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000000000000000
Cpus_allowed:   f
Cpus_allowed_list:      0-3
voluntary_ctxt_switches:        153465
nonvoluntary_ctxt_switches:     124897

 

6、监控-流量

一、通过查看对应 uid 目录下的 tcp_rcv 和 tcp_snd 两个人文件(模拟器内使用,真机内兼容性不好,所以尽量不使用)

  • adb shell cat /proc/uid_stat/<uid>/tcp_snd
  • adb shell cat /proc/uid_stat/<uid>/tcp_rcv

命令中的<uid>要替换成自己的 uid。这里统计的是总共的数据,如果要打点制图的话,需要用后一秒的数据减去前一秒的数据,就代表每秒发送/接收的,而且这俩值手机重启后是会被清零的

C:\Users\Admin>adb shell cat /proc/uid_stat/10060/tcp_snd  ## 截止到现在,一共发送的
62365

C:\Users\Admin>adb shell cat /proc/uid_stat/10060/tcp_rcv  ## 截止到现在,一共接收的
385664

 

二、通过 proc/net/xt_qtaguid/stats

  • adb shell cat /proc/net/xt_qtaguid/stats | grep <uid>

  命令中的<uid>要替换成自己的uid,这里的列太多,只需关注第 6 列的 rx_bytes 以及第 8 列的 tx_bytes 即可。这里的网络类型是 eth1 ,代表是本地网路连接,因为我们是用的虚拟机,所以会显示如此,但是真正用真机的过程中,一般是 wlan 以及 4G 之类的,我们可以根据不同的网络类型去进行过滤,出来我们的相关流量数据

  而且,这里我们显示出来的是两行,将两行相加,就是对应的流量使用情况,例rx_bytes=6468+407121

C:\Users\Admin>adb shell "cat /proc/net/xt_qtaguid/stats | grep 10060"
idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets t
x_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
8 eth1 0x0 10060 0 6468 50 10540 69 6468 50 0 0 0 0 10540 69 0 0 0 0 9 eth1 0x0 10060 1 407121 629 84821 697 407121 629 0 0 0 0 84821 697 0 0 0 0

 

三、通过PID下面的net/dev

  • adb shell cat /proc/<Pid>/net/dev

 

命令中的 <pid> 要替换成自己的 pid

Receive 里面看 eth0 或eth1 的 bytes ,就是发送的数据量,如果有多个 eth0 或者 eth1,就把 eth0 的全部加起来或者 eth1 的全部加起来,不要把 eth0 + eth1;

Transmit 里面看 eth0 或eth1 的 bytes ,就是接收的数据量

C:\Users\Admin>adb shell "cat /proc/1316/net/dev"
Inter-|   Receive                                                | Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
  sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0
    lo:  138333    1468    0    0    0     0          0         0   138333    1468    0    0    0     0       0          0 eth0: 67502526  876935    0    0    0     0          0         0 1093153548  639793    0    0    0     0       0          0 eth1:  440817     900    0    0    0     0          0         0   119085     920    0    0    0     0       0          0
  ifb0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0
  ifb1:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0

 

7、监控-启动时间

一、通过adb命令获取

  • adb shell am start -W <packageName>/<activityName>

分为冷启动和热启动:冷启动就是把后台杀死,启动该 app 的时间;热启动就是不杀掉应用的情况下启动。我们这里记录的是冷启动过程,也就是把 APP 先杀死,再启动,一般热启动的时间为 0

而且,我们只关注 TotalTime

C:\Users\Admin>adb shell am start -W tv.danmaku.bili/tv.danmaku.bili.ui.splash.SplashActivity
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=tv.danmaku.bili/.ui.splash.SplashActivity }
Status: ok
Activity: tv.danmaku.bili/.ui.splash.SplashActivity
ThisTime: 1264
TotalTime: 1264
Complete

 

 

看到结果如图:

APP自动化测试

8、监控-电量

获取手机电池信息,有很多方式,adb 命令不一定要通过数据线,通过 wifi 也可以

  • adb shell dumpsys battery
  • adb shell dumpsys battery set status 1
  • adb shell dumpsys battery set level 100
C:\Users\Admin>adb shell dumpsys battery  ## 获取手机当前的电量信息
Current Battery Service state:
  AC powered: true
  USB powered: false
  Wireless powered: false
  status: 5  ## 电池状态:2:充电状态 ,其他数字为非充电状态
  health: 1  ## 电池健康状态:只有数字2表示good
  present: true  ## 电池是否安装在机身
  level: 100  ## 电量: 百分比
  scale: 100
  voltage: 0  ## 电池电压
current now: -335232   ## 电流值,负数表示正在充电 temperature: 0  ## 电池温度,单位是0.1摄氏度 technology:  ## 电池种类 C:\Users\Admin>adb shell dumpsys battery set status 1 C:\Users\Admin>adb shell dumpsys battery set level 100 C:\Users\Admin>adb shell dumpsys battery Current Battery Service state: (UPDATES STOPPED -- use 'reset' to restart) AC powered: true USB powered: false Wireless powered: false status: 1 health: 1 present: true level: 100 scale: 100 voltage: 0 temperature: 0 technology:

 

获取电量消耗信息

  • adb shell dumpsys batterystats
  • adb shell dumpsys batterystats com.Package.name