小伙伴们大家好,今天主要分享的主题是Android App专项测试。如何进行Android App专项测试压力测试呢?我们主要通过Android平台的一门工具Monkey。在学习本门课程之前,如果你具有一定的Shell基础,将很有助于理解。
1. 为什么要开展压力测试?
2. 什么时候开展压力测试?
1.手工测试场景
2.自动测试场景
3.Monkey工具
4.ADB命令
5.Monkey Script
6.MonkeyRunner
7.压力测试结果
1.什么是Crash?
2.什么是ANR?
1.一个APP的压测实践
2.Monkey高级参数的应用
3.CRASH结果析取
4.ANR结果析取
5.Monkey Script实例
6.MonkeyRunner实例
提高产品稳定性
提高产品的留存率
首轮功能测试通过后
下班后的夜间进行
就拿查找实现自动化的话,对于手机来说它会
TouchInput(收集点击事件)–>KeyEvent(它会收到你点击键盘各种Key的事件)–>TouchSearch(收到你点击按钮的Touch事件)
然后就会返回一个联系人列表可以添加了
TouchSearch(收到你点击按钮的Touch事件)–>TouchName(对于手机来说同样收到一个Touch事件)
聊天嘛,你收到的也是一个Touch事件,因为你要点击用户头像,所以
TouchName(对于手机来说同样收到一个Touch事件)–>TouchFriend–>TouchKey(接着会受到你输入的各种文字)
在手机系统里,为了与它进行通讯,我们需要借助一个工具ADB
这里需要借助一部 手机 和一台 WIndows电脑 ,通过USB链接,此时我们还需要建立一个软的连接,这个连接全程就是Android Debug Bridge,也就是Android调试桥。
我们需要注意的两个地方:Crash 和 ANR
ANR
Application Not Responding,如下图:
准备Android SDK环境
准备Python环境
对于环境配置这里不做过多讲解
在手机开发者选项中,将USB调试勾上
确认手机和电脑已经连接成功
adb devices来确认:cmd
窗口输入adb devices
,有以下信息就说明已经建立连接
安装测试app :
adb install package.apk
发送测试指令 :
adb shell monkey 1000
之后会输出如下类似信息:
什么时候会出现两行ActivityResuming的信息呢,就是一个app从前台调入后台,又从后台调入前台就会出现这么一个信息.
Event injected:1000 表示我们输入的随机测试1000个事件,它完成的也是1000个事件.如果这里的数字与我们输入的数字小灯,则表明没有异常出现.如果有异常出现,则这个数字小于我们输入的数字.
获取程序包名 :
adb logcat | grep START
,
|
表示前一个命令的输出作为下一个命令的输入
grep START
表示抓取日志中包含有START标签的日志进行输出
这里我们主要关注cmp=
后面的内容,在/
之前的是app的包名,在/
后面的是当前Activity的类名.Activity我们暂时不许要太关注,我们只需要关注这个包名。
我们以计算器为例,当我们home返回桌面,点击进入计算器,cmd就会输出计算器的一些信息,如:
给指定包打压力 :
adb shell monkey -p [packagename] [次数,如1000]
,,如adb shell monkey -p com.android.calculator2 1000
,输出信息如下:
指定事件之间的间隔:
adb shell monkey --throttle
,例如adb shell monkey -p com.android.calculator2 --throttle 1000 10
指定随机生成数的seed值 :
adb shell monkey -s
,例如 :adb shell monkey -p com.android.calculator2 -s 100 50
,在重复执行一遍命令就可以复现上一条命令执行的结果,这里的seed次数100和执行事件数50保持遇上一条命令数目相同便可复现上一次结果。
设定触摸事件的百分比 :
adb shell --pct-touch
,意思就是monkey所有操作中点击事件占多大比例。例如 :adb shell monkey -v -p com.android.calculator2 --pct-touch 100 100
. ‘-v’参数表示列出所有操作详情。如下图,红色部分就是执行的操作,其中Action_down和Action_up是一个点击事件,成对出现。
设置动作事件百分比 :
adb shell monkey --pct-motion
,这个百分比和你其他事件之和要等于100。如果不等于100,它就会把剩余的比例随机操作。例如 :adb shell monkey -v -p com.android.calculator2 --pct-touch 50 --pct-motion 30 100
,执行后各事件百分比如下:
设定轨迹球事件的百分比 :
adb shell monkey --pct-trackball
设定基本导航事件的百分比,输入设备的上下左右 :
adb shell monkey --pct-nav
设定主要导航事件的百分比,兼容中间键,返回键,菜单按键 :
adb shell monkey --pct-majornav
与手机硬件相关的
设定系统导航事件的百分比,HOME,BACK,拨号及音量键 :
adb shell monkey --pct-syskeys
设定启动Activity的事件百分比 :
adb shell monkey --pct-appswitch
,假设我们指定了30%,有4个Activity,它就会有30%部分在4个Activity里进行切换
设定系统导航事件的百分比,HOME,BACK,拨号及音量键 :
adb shell monkey --pct-anyevent
Crash
忽略崩溃和异常 :
adb shell monkey --ignore-crashes
,monkey在遇到崩溃时会继续跑,直到遇见的崩溃数等于我们的设定数值。
ANR
忽略超时事件 :
adb shell monkey --ignore-timeouts
,monkey在遇到超时事件会继续跑,直到遇见的超时数等于我们的设定数值。
析取Crash的Exception信息
注意:在cmd命令控制台输出的信息中CRASH: 后面的内容可以复制出来交给开发人员进行解决,在输出信息末尾会有一个seed的值,拷贝这个值并在命令中加上[-s seed值]便可复现上一次的测试。如果在测试过程中忽略了crash而继续执行则无法获取到seed值。
析取ANR的Exception信息
注意:在cmd命令控制台输出的信息中NOT RESPONDING:后面会开始输出ANR错误的类名位置,后面会紧跟当时手机系统的一些信息,如cpu,内存以及其他的一系列的异常信息,全部打印了出来。当出现这种异常信息我们可以将这些信息发送给开发人员debug进行处理。
手动点击获得ANR异常,查看日志方法:
在cmd命令控制台,依次输入如下命令
- adb shell
- cd /data/anr/
- ls (会有一个traces.txt)
- more traces.txt
经历以上操作就可以把异常信息再控制台中输出了,我们可以把这些异常信息复制下来交由开发人员去分析。
执行Monkey脚本命令 :
adb shell monkey -f
可以帮我们完成点击操作
DispatchTrackball(long downtime,long eventide,int action,folat x,float y,float pressure,float size,int metstate,float xprecision,float yprecision,int device,int edgeflags)
downtime : 记录键最初被按下的时间
eventide : 事件发生的时间
action : 具体的操作过程
x,y : 坐标点
pressure : 压力的大小,范围是0-1
size : 触摸的一个即使值,范围是0-1
metstate : 当前按下met键的标识
xprecision : x坐标的精确值
yprecision : y坐标的精确值
device : 事件的来源,事件的来源是0-x,0表示不来自物理设备
edgeflags : 表示超出屏幕范围action 0代表按下,1代表抬起,x和y代表坐标点
DispatchPointer(long downtime,long eventide,int action,folat x,float y,float pressure,float size,int metstate,float xprecision,float yprecision,int device,int edgeflags)
downtime : 记录键最初被按下的时间
eventide : 事件发生的时间
action : 具体的操作过程
x,y : 坐标点
pressure : 压力的大小,范围是0-1
size : 触摸的一个即使值,范围是0-1
metstate : 当前按下met键的标识
xprecision : x坐标的精确值
yprecision : y坐标的精确值
device : 事件的来源,事件的来源是0-x,0表示不来自物理设备
edgeflags : 表示超出屏幕范围action 0代表按下,1代表抬起,x和y代表坐标点
DispatchString(String text)
LuanchActivity(Package,Activity)
UserWait(1000) , 传入毫秒数
DespatchPress(int keycode) , #keycode 66 返回键
缺点:执行脚本过程中无法实现截屏操作
脚本后缀名.script
1.启动app
2.点击输入框
3.输入查询词
4.点击键盘上的回车
5.点击搜索按钮
6.等待结果出现
7.点击clear按钮
在获取点击坐标点时我们需要用到android_sdk里面tools文件夹下的一个uiautomatorviewer的一个工具
使用:cmd命令进入到tools文件夹下,然后输入 ./uiautomatorviewer
uiautomatorviewer界面:
左上角两个手机图标是获取当前Android设备的界面
右下角bounds两个坐标点表示控件的左上角和右下角的坐标点。
脚本使用首先要从电脑push到手机中,命令如下:
adb shell ***.script /data/local/tmp/
此时继续执行脚本命令:
monkey -f ***.script
而此时回车并不能启动起我们指定的Activity而是超级用户,这里寻找原因就是我们的LaunchActivity()
命令行有问题
之所以出现这个问题是因为在app的AndroidManifest.xml
里面activity
标签没有android:exported="true"
这一行代码,这样外部就无法调用起Activity。
在一系列修改完成之后,在脚本里还需要在LaunchActivity()
里将后面的Activity加上完整路径,包名+类名,这样才能正确启动
void alert(String message,String title,String okTitle)
这里的脚本是一个python脚本,后缀名为.py
第一行表示是用Python编写的
第二行表示编码格式
第三行表示需要导入我们测试的模块
第四行表示执行alert命令
执行命令:
monkeyrunner ****.py
monkeyrunner 在android-sdk/tools下面
等待设备连接,如果有多个device id,则需要指明具体哪个设备
waitForConnection(float timeout,String deviceId)
, timeout单位为秒
拖动
drag(tuple start,tuple end, float duration ,integer steps)
, timeout单位为秒
start : 起始点
end : 目标点
duration : 手势持续时间
steps : 插值点的个数,默认为10
按键
press(String keycode,dictionary type)
,
keycode 名:DOWN,UP,DOWN_AND_UP
启动应用
startActivity(package+'/'+activity)
点击
touch(integer x,integer y,integer type)
x,y : 坐标值
type : DOWN,UP,DOWN_AND_UP
输入
type(String text)
截屏
MonkeyImage takeSnapshot()
,会返回MonkeyImage 类型数据
图像对比
boolean sameAs(MonkeyImage other,float percent)
保存图像
void writeToFile(String path,String format)
path : 保存路径
format : 保存格式,如.jpg,.png,.jpeg