#7 楼 @seveniruby 写这篇是说下目前重构了之前写的 shell 管理 monkey 压力测试,及重构过程和重构结果。没有侧重交付使用的表达,交付使用是我们内部专项的内容,写的内部 PPT 交付的手工测试执行组。付的源码中有说明,而且代码中有注释就没细写这部分内容。之前在犹豫是不是要把自己写的内部 PPT 发出来,是目前两项专项测试项内容。考虑自己写的是内部文档就没放出来。
使用方式就是设计主控逻辑的脚本进行测试,监控都是独立进程写的。脚本是设备端的 shell 脚本,用途是设备端后台执行,不用长连接 PC
两行代表一项测试
# 执行实例:
# 方式1 执行case.sh已写好的case:$1时长?秒; $2-用例编号;$3-用例参数
# monkey_test 60 0 "com.letv.app.appstore"
# monkey_timeout 60
# 方式2 按参数执行moneky语句:$1-时长; $2-限制范围;$3-事件比例; $4-monkey log文件名
# monkey_test 60 "-p com.letv.games" "--pct-touch 20 --pct-trackball 5 --pct-motion 35 --pct-flip 5 --pct-appswitch 30 --pct-anyevent 5" "letv_games"
# monkey_timeout 60
组件形式 APP 需要三行
monkey_test 7200 0 "com.letv.lesophoneclient"
##保持am唤起主activity,间隔1S如不显示则唤起
longam "com.letv.lesophoneclient" 7200 "com.letv.lesophoneclient/.ui.MainActivity"
monkey_timeout 600
#1 楼 @lihuazhang 控制了读写量,log 采用筛查方式,连续做个一两天的 monkey 压力,总体记录的量还可以承受。TV 和盒子可以直接写外接 u 盘里。目前实际使用中 30 几小时的压力测试没什么问题。
逻辑上通过 SurfaceFlinger 判定界面显示状态,未锁屏则发键值 26 锁屏;锁屏壁纸界面则滑屏就是打开,挺好实现的逻辑。
设备端 shell 脚本我是这么写的,逻辑上是这样的,写成 java 脚本也可以。
#锁屏函数$1:0--lock;1--unlock
#屏幕物理分辨率
export wm_size_x=`wm size|busybox awk -F" |x" '{print $(NF-1)}'`
export wm_size_y=`wm size|busybox awk -F" |x" '{print $NF}'`
lock(){
while true;do
case `dumpsys SurfaceFlinger|grep "|....|"|busybox awk 'BEGIN{r="o"}{if($NF=="com.android.systemui.ImageWallpaper")r="l"}END{print NR-1 r}'` in
"1o")
local state=0
;;
"3l")
local state=1
;;
*)
local state=2
;;
esac
case $1 in
0)
if [ $state -ne 0 ];then
input keyevent 26
else
break
fi
sleep 1
;;
1)
if [ $state -eq 0 ];then
#我这是上滑屏解锁,其他的改下参数就好了
input keyevent 26&&sleep 1&&input swipe $((wm_size_x/2)) $((4*wm_size_y/5)) $((wm_size_x/2)) $((wm_size_y/5))
elif [ $state -eq 1 ];then
input swipe $((wm_size_x/2)) $((4*wm_size_y/5)) $((wm_size_x/2)) $((wm_size_y/5))
else
break
fi
sleep 1
;;
esac
done
}
#23 楼 @andyguo 开始写的时候测试的是高通取的 cpu 温度,实际测试 cpu 温度和电池温度一直一样,后来发现 MTK 不兼容就做了兼容处理,全部取了电池问题,模板没改还是 cpu 温度。
下面是取温度的兼容,看注释。存在哪个取哪个,毕竟不同平台情况互斥,不会共存。
# 判定高通和 MTK 兼容获取电池温度不同
if [ -f /sys/class/power_supply/battery/temp ];then
temp="/sys/class/power_supply/battery/temp"
elif [ -f /sys/class/power_supply/battery/batt_temp ];then
temp="/sys/class/power_supply/battery/batt_temp"
fi
把当前我自己在项目中使用的实例发上来了,可以参考,定制为所需的执行逻辑。
monkey 压力执行脚本:(http://pan.baidu.com/s/1jG2dtHG)
筛查异常:(logcat -v time)(http://pan.baidu.com/s/1gdg4K99)
BTM(电量 - 电压 - 温度监控):(http://pan.baidu.com/s/1kT92OJX)
其中把结果保存在/data/目录下是由于测试了文件管理和图库,结果放 sdcard 下可能被 monkey 操作。就换了文件管理类 app 控制不了的 data 目录保存结果。
#32 楼 @zongguanxian 只考虑了测试数据抓取和引导分析数据的方向,主要目的是像过筛子一样,先过第一道筛子:
1、PSS 峰值越高可优化空间越大,PSS 峰值降序排列,可以优先看优化利益大的进程。
2、PSS 极值差越大,被怀疑内存泄露的可能性越大,极值差降序排列优先看风险最高的。
3、单进程走势图分析,观察 PSS 波动大的部分的 Activity 变化,及对应 log 时间分析操作,进一步确定导致内存波动的操作;可以针对这些操作做进一步测试和跟踪分析。
所谓大浪淘沙,得先让沙子沉下来,再取沙子来分析。
#2 楼 @zongguanxian 这是有局限的,只限于有句柄变化的测试场景,误差就是取次 SurfaceFlinger 数据的差异,而且每次取数据都是开销差不多的时间做减法后精度在 0.01 吧。SurfaceFlinger 是显示帧的管理,屏幕完全显示出来就看屏幕硬件驱动的性能了,基本可忽略。
视频类合成的帧是独立显示的 HWC_FRAMEBUFFER_TARG 代表了合成的图像,至于它的句柄变化没细研究变化的规律。
adb shell
time tmp=`cat /proc/uptime&&dumpsys SurfaceFlinger|grep "|....|"
0m0.02s user 0m0.01s system
time echo "$tmp"|busybox awk '{if(NR==1){print $1 }else{print $0}}'|busybox awk -F "|" '{if(NR==1){t=$1}else{if(NR>2){print t","substr($1,2,length($1)-2)","substr($2,2,length($2)-2)","substr($NF,2,length($NF)-3)}}}'
0m0.00s real 0m0.00s user 0m0.00s system
log 筛查处理的是用-v time 格式获取的 log。
再有,如果是在 windows 上编辑 shell 脚本,需要注意文档格式为 unix,字符编码为 utf8,使用 Notpad++ 转一下文档格式就好了。
#9 楼 @babyshine 注释了,需要修改 monkey 语句,设备端的脚本用到了 busybox,本身脚本是去除了,moneky 测试逻辑,毕竟这个是和测试目的和设备相关的,需要按需定制。
#10 楼 @happystone
#10 楼 @happystone
1.两个方式,一个是判定是否有退出的确定框弹出,有的话就取消。再一个是 uiautomator dump 取布局的 xml 分析
dumpsys SurfaceFlinger|grep "|....|" 可以取到当前显示的情况,可以取到是否有确定弹出框的布局。
uiautomator dump /sdcard/check.xml 出的 xml,busybox sed -i 's/<node/\n<node/g' /sdcard/check.xml node 前加回车就很好分析了。而且对于很多 apk 会把设置状态保存在/data/data/包名 下会有对应的 xml,可以查下你要测试的又没有,取文件判定登陆状态也是个思路
2.初始化其实就是可以用 shell 控制在哪也操作,monkey 就负责点就是了,配下操作事件类型和比例。shell 控制当前操作的 activity。跑乱了就听掉 monkey,不退 app 直接从当前状态切换回登陆状态。
这个实现思路可以用 case 语句,对每种情况绑定恢复初始状态的操作,这样不论需要初始化时状态是什么都可以恢复初始页面。
#5 楼 @happystone 比如你所说的保持登录状态,后台轮询脚本可以判定 app 显示状态,如果是退出框则点取消,如果这样还被退,就在判定账号退出后,执行初始化重新登录。
#4 楼 @happystone 数据可视化可以用 highcharts 框架,python 处理数据,我的监控方案及很多数据展示的需求都是这么做的。本来我也计划着要写下 shell 控制 monkey 执行配合监控抓取数据,轮询筛查 log 精简 log 量,最终脚本筛查统计 log 便于进一步分析,写完再发。对于需要 monkey 保持特定场景执行,简单的做法就是 shell 中做控制及当前状态判定。保持登录状态不好控制,但处于未登录状态初始化重新登录时可行的。
monkey 的 log 对 ANR 和 crash 的输出在 2 输出流,结果重定向最好 1> /mnt/sdcard/monkey_test.txt 2>&1 &; 这样在 monkey_test.txt 就可以筛查到 ANR 和 crash,并且知道异常前的操作
#30 楼 @seveniruby 哎,测试行业混迹 8 年了,从手游到安卓 TV,从 java 功能机到智能机,从功能到自动化再到性能,折腾来折腾去。这是总结在乐视实践性能优化的过程,一个人从零到搭建方案建立流程,持续调整优化改善。根本目标是控制用户体验改善和版本性能情况监控。性能优化本身不是测试一个部门搞得定的,所以致力于推动多部门间的合作。总结的就是推动的办法,及收集数据作为推动的证据。设计测试筛查方案引导研发资源投入到明显改善用户体验的点上。
工具更新了几个问题:
1、获取 activity 的源数据格式 TV 和手机格式不同,按正向第五个取数据而不是之前的倒数取数据
mFocusedApp=AppWindowToken{425a3510 token=Token{42665e80 ActivityRecord{42665d30 u0 com.letv.leso/.activity.SearchBoardActivity}}}
mFocusedApp=AppWindowToken{2a336cc7 token=Token{18b95356 ActivityRecord{a3b7971 u0 com.android.settings/.UsbSettings t34}}}
2、在手机系统性能慢的时候,退出 app 存在虚拟机退出和进程退出之间存在时间差,” dumpsys meminfo 进程 PID “未取到数据但” cat /proc/进程 pid/smaps|grep Pss 求和取 Pss“取到了。最终处理 csv 到 json 过程有处理错误。