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,不能指定具體頁面、功能

二、框架思路

先來一張圖,然後再具體說明

首先肯定需要一臺服務器,系統不限,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文件和截圖發過去就好了

釘釘消息效果圖:

點擊查看詳情跳轉到html網頁

7、自動報bug、驗證bug(代碼調用接口、seleniumUI自動化)

自動報bug:就是把錯誤日誌寫到你的bug裏,bug管理工具一般都是web端的,比如jira、tfs、Bugtags、禪道、Bugzilla等等,操作這些網站可以考虛用selenium寫webUI自動化來實現自動報bug,也可以用代碼直接調用接口來實現自動報bug,接口穩定一點。

驗證bug、關閉bug:比如連續3天沒有出現上次的崩潰或相同send值跑了幾次沒有復現,就可以調用接口或seleniumUI自動化把上次的提的bug關掉。

到此就實現了monkey的全自動化,因爲monkey的腳本是自動生成的,所以不需要人工寫腳本,所以才能實現全自動化。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章