monkey自动化测试框架(从下载安装app到发送报告的持续集成)

一、monkey介绍

1、Monkey程序由Android系统自带,使用Java语言写成,在Android文件系统中的存放路径是: /system/framework/monkey.jar; Monkey.jar程序是由一个名为“monkey”的Shell脚本来启动执行,shell脚本在Android文件系统中 的存放路径是:/system/bin/monkey;

2、作用:测试androidApp的稳定性、健壮性

3、优点:自动生成脚本、日志能直接定位到被测app具体代码行数、随机性

4、缺点:测试目标为整个app,不能指定具体页面、功能

二、框架思路

先来一张图,然后再具体说明

monkey自动化测试框架(从下载安装app到发送报告的持续集成)_第1张图片

首先肯定需要一台服务器,系统不限,win、mac、linux,都可以

1、持续集成

这个首选肯定是jenkins,主要是用来拉取被测app的代码、打包成apk安装包、定时构建测试

2、下载被测app、安装app(代码)

如果开发已经做好现成的apk供你下载,那就不需要自己拉代码打包了,只需要利用代码把apk下载到你的服务器上,然后调用adb命令安装。

3、测试前的准备工作(UI自动化)

monkey测试前肯定要检查一下,被测app的状态是否符合要求,比如要打开wifi、登录账号、切换测试环境、等等操作,这些就需要用UI自动化来实现,目前有两种框架可选uiautomator2.0和appium,我用的是uiautomator2.0。

4、执行monkey测试(shell脚本)

这里就开始执行monkey测试了,把monkey的指令写到一个shell脚本中,再把shell脚本push到手机里触发执行,该脚本还包含其他功能,比如:统计手机信息(内存、手机型号、app版本、安卓版本等等)、把monkey产生的日志分类,将正常log和异常log分别写入文件,放到手机的指定路径下、记录开始测试时间和结束测试时间、发生崩溃页面的截图功能。这些操作都要写到shell脚本中。

#!/system/bin/sh
dire="/mnt/sdcard/A-monkey/"
filename="/mnt/sdcard/A-monkey/error"
fileout="/mnt/sdcard/A-monkey/result"
filedetail="/mnt/sdcard/A-monkey/detail"

#获取手机信息
info(){
    devices_name=`getprop ro.product.model` #设备名称
    android_version=`getprop ro.build.version.release` #安卓版本
    PHONE_PRODUCER=`getprop ro.product.brand` #手机厂家
    SCREEN_SIZE=`wm size` #分辨率
    SCREEN_SIZE1=${SCREEN_SIZE#*:} #分辨率
    phone_sdk=`getprop ro.build.version.sdk` #sdk版本
    phone_udid=`getprop ro.serialno` #udid
    phone_ip=`ip -f inet addr show wlan0` #ip地址  ifconfig | grep Mask
    phone_ip1=${phone_ip#*inet}
    phone_ip2=${phone_ip1%/*}
    BabyfsVersion=`dumpsys package cn.babyfs.android|grep versionName` #宝玩app版本
    BabyfsVersion1=${BabyfsVersion#*=} #宝玩app版本
    WeChatVersion=`dumpsys package com.tencent.mm|grep versionName` #微信的版本
    WeChatVersion1=${WeChatVersion#*=} #微信的版本
    CpuVersion=`getprop ro.product.board` #处理器的型号
    MemTotal=`cat /proc/meminfo|grep MemTotal` #总内存
    MemTotal1=${MemTotal#*:}  #删除左边
    MemTotal2=${MemTotal1%kB*} #删除右边
    MemTotal3=`expr $MemTotal2 / 1024`  #除法
    MemFree=`cat /proc/meminfo|grep MemFree` #可用内存
    MemFree1=${MemFree#*:}
    MemFree2=${MemFree1%kB*}
    MemFree3=`expr $MemFree2 / 1024`
    
    printf "手机厂商: $PHONE_PRODUCER\n">>$filedetail
    printf "设备名称: $devices_name\n">>$filedetail
    printf "安卓版本: $android_version\n">>$filedetail
    printf "分辨率: $SCREEN_SIZE1\n">>$filedetail
    printf "处理器型号:$CpuVersion\n">>$filedetail
    
    if [ -z $BabyfsVersion ]; then
        printf "宝玩app版本: 没有安装宝玩app\n">>$filedetail
    else
        printf "宝玩app版本: $BabyfsVersion1\n">>$filedetail
    fi    
    
    
    if [ -z $WeChatVersion ]; then
        printf "微信版本: 没有安装微信\n">>$filedetail
    else
        printf "微信版本: $WeChatVersion1\n">>$filedetail
    fi    
    
    printf "sdk版本: $phone_sdk\n">>$filedetail
    printf "udid: $phone_udid\n">>$filedetail
    if [ -z $phone_ip2 ]; then
        printf "ip地址: 手机未连接wifi\n">>$filedetail
    else
        printf "ip地址:$phone_ip2\n">>$filedetail
    fi


    if [ $MemTotal3 -gt 7000 -a $MemTotal3 -le 8000 ]; then
        printf "总内存: 8g\n">>$filedetail
    elif [ $MemTotal3 -gt 6000 -a $MemTotal3 -le 7000 ]; then
        printf "总内存: 7g\n">>$filedetail
    elif [ $MemTotal3 -gt 5000 -a $MemTotal3 -le 6000 ]; then
        printf "总内存: 6g\n">>$filedetail
    elif [ $MemTotal3 -gt 4000 -a $MemTotal3 -le 5000 ]; then  #大于and小于等于
        printf "总内存: 5g\n">>$filedetail
    elif [ $MemTotal3 -gt 3000 -a $MemTotal3 -le 4000 ]; then
        printf "总内存: 4g\n">>$filedetail
    elif [ $MemTotal3 -gt 2000 -a $MemTotal3 -le 3000 ]; then
        printf "总内存: 3g\n">>$filedetail
    elif [ $MemTotal3 -gt 1000 -a $MemTotal3 -le 2000 ]; then
        printf "总内存: 2g\n">>$filedetail
    elif [ $MemTotal3 -gt 500 -a $MemTotal3 -le 1000 ]; then
        printf "总内存: 1g\n">>$filedetail
    else
        printf "内存判断错误\n">>$filedetail
    fi    
    printf "可用内存: $MemFree3 MB\n">>$filedetail
    printf "\n">>$filedetail
}

#monkey执行之前的动作
beforemonkey(){
if [ ! -d "$dire" ]; then
    mkdir "$dire"
fi
printf "\n">$filedetail

info

printf "测试开始时间   $(date "+%Y-%m-%d %H:%M:%S")\n">>$filedetail
}

#monkeytest(){
#monkey -p cn.fanting.notpadnew --throttle 700 --ignore-crashes --monitor-native-crashes --ignore-security-exceptions --ignore-timeouts --ignore-native-crashes  --pct-touch 65 --pct-appswitch 5 --pct-majornav 10 --pct-syskeys 10 --pct-nav 10 -v -v -v 100000 1>/mnt/sdcard/A-monkey/info.txt 2>/mnt/sdcard/A-monkey/error.txt
#}
#有错误就停止测试
monkeytest(){
monkey -p cn.fanting.notpadnew --throttle 700 --monitor-native-crashes --ignore-native-crashes  --pct-touch 80 --pct-syskeys 10 --pct-appswitch 10 -v -v -v 50000 1>/mnt/sdcard/A-monkey/info 2>/mnt/sdcard/A-monkey/error
}

#monkey执行之后的动作
aftermonkey(){
screencap -p $dire/error.png  #截图
CRASH=`grep -o 'CRASH: ' $filename | wc -l`
error=`grep -o 'error' $filename | wc -l`
ANR=`grep -o 'ANR' $filename | wc -l`
NullPointer=`grep -o 'Short Msg: java.lang.NullPointerException' $filename | wc -l`
ArrayIndexOutOfBounds=`grep -o 'Short Msg: java.lang.ArrayIndexOutOfBoundsException' $filename | wc -l`
lassNotFound=`grep -o 'CShort Msg: java.lang.lassNotFoundException' $filename | wc -l`
ClassCast=`grep -o 'Short Msg: java.lang.ClassCastException' $filename | wc -l`
Arithmetic=`grep -o 'Short Msg: java.lang.ArithmeticException' $filename | wc -l`
IllegalArgument=`grep -o 'Short Msg: java.lang.IllegalArgumentException' $filename | wc -l`
FileNotFound=`grep -o 'Short Msg: java.lang.FileNotFoundException' $filename | wc -l`
NumberFormat=`grep -o 'Short Msg: java.lang.NumberFormatException' $filename | wc -l`
StackOverflow=`grep -o 'Short Msg: java.lang.StackOverflowError' $filename | wc -l`
OutOfMemory=`grep -o 'Short Msg: java.lang.OutOfMemoryError' $filename | wc -l`
IllegalState=`grep -o 'Short Msg: java.lang.IllegalStateException' $filename | wc -l`
UnsatisfiedLink=`grep -o 'Short Msg: java.lang.UnsatisfiedLinkError' $filename | wc -l`
StringIndexOutOfBounds=`grep -o 'Short Msg: java.lang.StringIndexOutOfBoundsException' $filename | wc -l`
Nativecrash=`grep -o 'Short Msg: Native crash' $filename | wc -l`
sleep 2
printf "测试结束时间   $(date "+%Y-%m-%d %H:%M:%S")\n">>$filedetail
printf "\n">>$filedetail

printf "---------------错误日志统计--------------\n">$fileout
printf "%-33s %-10s\n" 错误类型 出现次数>>$fileout
printf "\n">>$fileout
printf "CRASH                          $CRASH\n">>$fileout
printf "error                          $error\n">>$fileout
printf "ANR                            $ANR\n">>$fileout
printf "NullPointer(空指针)             $NullPointer\n">>$fileout
printf "ArrayIndexOutOfBounds(数据溢出) $ArrayIndexOutOfBounds\n">>$fileout
printf "ClassNotFound(类不存在)         $lassNotFound\n">>$fileout
printf "ClassCast(类型转换出错)          $ClassCast\n">>$fileout
printf "Arithmetic(数学运算异常)         $Arithmetic\n">>$fileout
printf "IllegalArgument(方法参数异常)    $IllegalArgument\n">>$fileout
printf "FileNotFound(文件未找到)        $FileNotFound\n">>$fileout
printf "NumberFormat(数值转换异常)      $NumberFormat\n">>$fileout
printf "StackOverflow(线程栈满)         $StackOverflow\n">>$fileout
printf "OutOfMemory(内存溢出)           $OutOfMemory\n">>$fileout
printf "IllegalState(无效状态异常)      $IllegalState\n">>$fileout
printf "UnsatisfiedLink(未获取到so库包)  $UnsatisfiedLink\n">>$fileout
printf "StringIndexOutOfBounds(字符串截取异常)  $StringIndexOutOfBounds\n">>$fileout
printf "Native crash(底层崩溃)          $Nativecrash\n">>$fileout
#加颜色格式
#printf "\e[31m Hello World \e[0m \n">>$fileout
}
#monkey执行之前的动作
beforemonkey
#echo monkey开始执行
monkeytest
#monkey执行之后的动作
aftermonkey

5、测试后的工作,生成报告(代码)

接下来就是pull出日志、截图、手机信息,对这些东西做处理。先把日志和手机信息写成html文件,然后重命名放到自己搭建的webserver(网站)中,把截图也放到webserver(网站)中,供别人查看。当然你事先要先搭建好网站,可以选择tomcat或jetty这种开源框架。

6、测试后续工作,发送报告(代码)

发送报告主要有两种形式,一是调用钉钉机器人发送到钉钉群里,二是发送邮件给相关人员。

钉钉消息需要包含:手机信息、错误日志类型分析、错误日志摘要、html报告的链接、截图的链接

邮件:直接把html文件和截图发过去就好了

钉钉消息效果图:

monkey自动化测试框架(从下载安装app到发送报告的持续集成)_第2张图片

monkey自动化测试框架(从下载安装app到发送报告的持续集成)_第3张图片

点击查看详情跳转到html网页

monkey自动化测试框架(从下载安装app到发送报告的持续集成)_第4张图片

7、自动报bug、验证bug(代码调用接口、seleniumUI自动化)

自动报bug:就是把错误日志写到你的bug里,bug管理工具一般都是web端的,比如jira、tfs、Bugtags、禅道、Bugzilla等等,操作这些网站可以考虚用selenium写webUI自动化来实现自动报bug,也可以用代码直接调用接口来实现自动报bug,接口稳定一点。

验证bug、关闭bug:比如连续3天没有出现上次的崩溃或相同send值跑了几次没有复现,就可以调用接口或seleniumUI自动化把上次的提的bug关掉。

到此就实现了monkey的全自动化,因为monkey的脚本是自动生成的,所以不需要人工写脚本,所以才能实现全自动化。

 

 

 

 

你可能感兴趣的:(app性能)