修改時間 |
修改內容 |
修改人 |
2016.6.20 |
創建 |
劉永志 |
2016.6.29 |
完成 |
劉永志 |
Monkey簡介:
Android SDK自帶的命令行測試工具,向設備發送偽隨機事件流,對應用程序進行進行穩定性測試。
Monkey的優勢與缺陷:
優勢:
- 脫離Case的依賴
- 可封裝自動化執行
- 可封裝后作為客戶端性能測試的驅動
缺陷:
- 完全隨機,不可控
-
不支持IOS系統
Monkey命令及參數:
基本語法如下:
$ adb shell monkey [options] <event-count>
如果不指定options,Monkey將以無反饋模式啟動,並把事件任意發送到安裝在目標環境中的全部包。下面是一個更為典型的命令行示例,它啟動指定的應用程序,並向其發送500個偽隨機事件:
$ adb shell monkey -p your.package.name -v 500
一些常用的參數信息。
Category |
Option |
Description |
General |
--help |
Prints a simple usage guide.
獲取幫助信息。 |
|
-v |
Each -v on the command line will increment the verbosity level. Level 0 (the default) provides little information beyond startup notification, test completion, and final results. Level 1 provides more details about the test as it runs, such as individual events being sent to your activities. Level 2 provides more detailed setup information such as activities selected or not selected for testing.
命令行的每一個-v將增加反饋信息的級別。Level 0(缺省值)除啟動提示、測試完成和最終結果之外,提供較少信息。Level 1提供較為詳細的測試信息,如逐個發送到Activity的事件。Level 2提供更加詳細的設置信息,如測試中被選中的或未被選中的Activity。 |
Events
事件 |
-s <seed> |
Seed value for pseudo-random number generator. If you re-run the Monkey with the same seed value, it will generate the same sequence of events.
偽隨機數生成器的seed值。如果用相同的seed值再次運行Monkey,它將生成相同的事件序列。 |
|
--throttle <milliseconds> |
Inserts a fixed delay between events. You can use this option to slow down the Monkey. If not specified, there is no delay and the events are generated as rapidly as possible.
在事件之間插入固定延遲。通過這個選項可以減緩Monkey的執行速度。如果不指定該選項,Monkey將不會被延遲,事件將盡可能快地被產成。 |
|
--pct-touch <percent> |
Adjust percentage of touch events. (Touch events are a down-up event in a single place on the screen.)
調整觸摸事件的百分比(觸摸事件是一個down-up事件,它發生在屏幕上的某單一位置)。 |
|
--pct-motion <percent> |
Adjust percentage of motion events. (Motion events consist of a down event somewhere on the screen, a series of pseudo-random movements, and an up event.)
調整動作事件的百分比(動作事件由屏幕上某處的一個down事件、一系列的偽隨機事件和一個up事件組成)。 |
|
--pct-trackball <percent> |
Adjust percentage of trackball events. (Trackball events consist of one or more random movements, sometimes followed by a click.)
調整軌跡事件的百分比(軌跡事件由一個或幾個隨機的移動組成,有時還伴隨有點擊)。 |
|
--pct-nav <percent> |
Adjust percentage of "basic" navigation events. (Navigation events consist of up/down/left/right, as input from a directional input device.)
調整"基本"導航事件的百分比(導航事件由來自方向輸入設備的up/down/left/right組成)。 |
|
--pct-majornav <percent> |
Adjust percentage of "major" navigation events. (These are navigation events that will typically cause actions within your UI, such as the center button in a 5-way pad, the back key, or the menu key.)
調整"主要"導航事件的百分比(這些導航事件通常引發圖形界面中的動作,如:5-way鍵盤的中間按鍵、回退按鍵、菜單按鍵) |
|
--pct-syskeys <percent> |
Adjust percentage of "system" key events. (These are keys that are generally reserved for use by the system, such as Home, Back, Start Call, End Call, or Volume controls.)
調整"系統"按鍵事件的百分比(這些按鍵通常被保留,由系統使用,如Home、Back、Start Call、End Call及音量控制鍵)。 |
|
--pct-appswitch <percent> |
Adjust percentage of activity launches. At random intervals, the Monkey will issue a startActivity() call, as a way of maximizing coverage of all activities within your package.
調整啟動Activity的百分比。在隨機間隔里,Monkey將執行一個startActivity()調用,作為最大程度覆蓋包中全部Activity的一種方法。 |
|
--pct-anyevent <percent> |
Adjust percentage of other types of events. This is a catch-all for all other types of events such as keypresses, other less-used buttons on the device, and so forth.
調整其它類型事件的百分比。它包羅了所有其它類型的事件,如:按鍵、其它不常用的設備按鈕、等等。 |
Constraints
約束限制 |
-p <allowed-package-name> |
If you specify one or more packages this way, the Monkey will only allow the system to visit activities within those packages. If your application requires access to activities in other packages (e.g. to select a contact) you'll need to specify those packages as well. If you don't specify any packages, the Monkey will allow the system to launch activities in all packages. To specify multiple packages, use the -p option multiple times — one -p option per package.
如果用此參數指定了一個或幾個包,Monkey將只允許系統啟動這些包里的Activity。如果你的應用程序還需要訪問其它包里的Activity(如選擇取一個聯系人),那些包也需要在此同時指定。如果不指定任何包,Monkey將允許系統啟動全部包里的Activity。要指定多個包,需要使用多個 -p選項,每個-p選項只能用於一個包。 |
|
-c <main-category> |
If you specify one or more categories this way, the Monkey will only allow the system to visit activities that are listed with one of the specified categories. If you don't specify any categories, the Monkey will select activities listed with the category Intent.CATEGORY_LAUNCHER or Intent.CATEGORY_MONKEY. To specify multiple categories, use the -c option multiple times — one -c option per category.
如果用此參數指定了一個或幾個類別,Monkey將只允許系統啟動被這些類別中的某個類別列出的Activity。如果不指定任何類別,Monkey將選 擇下列類別中列出的Activity: Intent.CATEGORY_LAUNCHER或Intent.CATEGORY_MONKEY。要指定多個類別,需要使用多個-c選項,每個-c選 項只能用於一個類別。 |
Debugging
調試 |
--dbg-no-events |
When specified, the Monkey will perform the initial launch into a test activity, but will not generate any further events. For best results, combine with -v, one or more package constraints, and a non-zero throttle to keep the Monkey running for 30 seconds or more. This provides an environment in which you can monitor package transitions invoked by your application.
設置此選項,Monkey將執行初始啟動,進入到一個測試Activity,然后不會再進一步生成事件。為了得到最佳結果,把它與-v、一個或幾個包約 束、以及一個保持Monkey運行30秒或更長時間的非零值聯合起來,從而提供一個環境,可以監視應用程序所調用的包之間的轉換。 |
|
--hprof |
If set, this option will generate profiling reports immediately before and after the Monkey event sequence. This will generate large (~5Mb) files in data/misc, so use with care. See Traceview for more information on trace files.
設置此選項,將在Monkey事件序列之前和之后立即生成profiling報告。這將會在data/misc中生成大文件(~5Mb),所以要小心使用它。 |
|
--ignore-crashes |
Normally, the Monkey will stop when the application crashes or experiences any type of unhandled exception. If you specify this option, the Monkey will continue to send events to the system, until the count is completed.
通常,當應用程序崩潰或發生任何失控異常時,Monkey將停止運行。如果設置此選項,Monkey將繼續向系統發送事件,直到計數完成。 |
|
--ignore-timeouts |
Normally, the Monkey will stop when the application experiences any type of timeout error such as a "Application Not Responding" dialog. If you specify this option, the Monkey will continue to send events to the system, until the count is completed.
通常,當應用程序發生任何超時錯誤(如"Application Not Responding"對話框)時,Monkey將停止運行。如果設置此選項,Monkey將繼續向系統發送事件,直到計數完成。 |
|
--ignore-security-exceptions |
Normally, the Monkey will stop when the application experiences any type of permissions error, for example if it attempts to launch an activity that requires certain permissions. If you specify this option, the Monkey will continue to send events to the system, until the count is completed.
通常,當應用程序發生許可錯誤(如啟動一個需要某些許可的Activity)時,Monkey將停止運行。如果設置了此選項,Monkey將繼續向系統發送事件,直到計數完成。 |
|
--kill-process-after-error |
Normally, when the Monkey stops due to an error, the application that failed will be left running. When this option is set, it will signal the system to stop the process in which the error occurred. Note, under a normal (successful) completion, the launched process(es) are not stopped, and the device is simply left in the last state after the final event.
通常,當Monkey由於一個錯誤而停止時,出錯的應用程序將繼續處於運行狀態。當設置了此選項時,將會通知系統停止發生錯誤的進程。注意,正常的(成功的)結束,並沒有停止啟動的進程,設備只是在結束事件之后,簡單地保持在最后的狀態。 |
|
--monitor-native-crashes |
Watches for and reports crashes occurring in the Android system native code. If --kill-process-after-error is set, the system will stop.
監視並報告Android系統中本地代碼的崩潰事件。如果設置了--kill-process-after-error,系統將停止運行。 |
|
--wait-dbg |
Stops the Monkey from executing until a debugger is attached to it.
停止執行中的Monkey,直到有調試器和它相連接。 |
來自 <https://developer.android.com/studio/test/monkey.html>
Monkey使用實例:
- 下載AndroidSDK
-
配置Android 環境變量
添加環境變量Android_HOME, 值是Android SDK的路徑;
Android SDK下的platform-tools路徑和tools路徑添加到環境變量Path (%ANDROID_HOME%\platform-tools; %ANDROID_HOME%\tools;)
- 獲取包名
- 連接設備或啟動模擬器
- 執行Monkey測試
adb shell monkey -p com.nyts.sport --pct-touch 30 --pct-motion 30 --pct-trackball 0 --pct-nav 0 --pct-majornav 20 --pct-appswitch 10 --pct-anyevent 10 -s(指定seed值) 12867 -v --throttle(指定時間間隔) 300 20000 >MonkeyTest.txt |
-
Monkey執行結果分析
打開日志文件,查找關鍵字"ANR","Fatal","CRASH","Exception","androidruntime","out of memory", "null pointer"若存在,則說明發生異常。
打開日志文件,查找關鍵字"Finished",若存在,則證明Monkey正常結束
-
收集出錯相關信息,發給研發
- 執行后的手機截圖
- monkey手機的日志文件
- monkey的測試結果
- 被測試手機信息
Monkey使用技巧:
Monkey的運行停止條件:
- 如果限定了Monkey運行在一個或幾個特定的包上,當試圖跳轉到其他包的時候,停止運行。
- 如果應用程序崩潰或接收到任何失控異常,Monkey將停止並報錯。
- 如果應用程序產生了應用程序不響應(application not responding)的錯誤,Monkey將會停止並報錯。(ANR異常)
- 向系統發送指定的事件,並計數完成
自動化集成:
DOS版本日志檢查:
@ECHO OFF
ECHO.:::::::::::::::::::::::::::::::::::::::::::::::::
ECHO.:: 分析Monkey日志 ::
ECHO.:: 作者:Findyou ::
ECHO.:: 版本 V1.0.1 ::
ECHO.:: 時間:2014.08.26 ::
ECHO.:::::::::::::::::::::::::::::::::::::::::::::::::
REM 方法一:手動設置Monkey日志路徑
SET monkeyLogFile=F:\Monkey\20140808\FindyouV1.0.0\20140825181801_monkey.log
REM 方法二:直接將Monkey日志拖到此bat文件上
IF NOT "%1"=="" SET monkeyLogFile=%1
ECHO.[ INFO ] Monkey日志: %monkeyLogFile%
ECHO.[ INFO ] 開始分析
SET blnException=0
ECHO.
ECHO.
REM 如果覺得分析太快,沒有感覺,把下面注釋去掉假裝分析中,有停頓感
REM ping -n 2 127.0.0.1>nul
::ANR日志
FOR /F "delims=" %%a IN ('FINDSTR /C:"ANR" %monkeyLogFile%') DO (
SET strANR=%%a
)
::崩潰日志
FOR /F "delims=" %%a IN ('FINDSTR /C:"CRASH" %monkeyLogFile%') DO (
SET strCRASH=%%a
)
::異常日志
FOR /F "delims=" %%a IN ('FINDSTR /C:"Exception" %monkeyLogFile%') DO (
SET strException=%%a
)
::正常
FOR /F "delims=" %%a IN ('FINDSTR /C:"Monkey finished" %monkeyLogFile%') DO (
SET strFinished=%%a
)
IF NOT "%strANR%" == "" (
ECHO.[ INFO ] 分析Monkey日志存在: ANR
ECHO.[ INFO ] ------------------------------------
ECHO. "%strANR%"
SET /a blnException+=1
ECHO.
)
IF NOT "%strCRASH%" == "" (
ECHO.[ INFO ] 分析Monkey日志存在: CRASH
ECHO.[ INFO ] ------------------------------------
ECHO. "%strCRASH%"
SET /a blnException+=1
ECHO.
)
IF NOT "%strException%" == "" (
ECHO.[ INFO ] 分析Monkey日志存在: 異常
ECHO.[ INFO ] ------------------------------------
ECHO. "%strException%"
SET /a blnException+=1
)
IF NOT "%strFinished%" == "" (
ECHO.[ INFO ] 分析Monkey日志存在: 執行成功標記
ECHO.[ INFO ] ------------------------------------
ECHO. "%strFinished%"
ECHO.
) ELSE (
IF %blnException% EQU 0 ECHO.[ INFO ] 分析Monkey日志結果: Monkey執行異常中斷,請重新執行Monkey腳本!
ECHO.
)
REM 如果blnException不為0,說明存在異常,改變字體為淡紫色
IF %blnException% NEQ 0 (
Color 0D
ECHO.[ INFO ] 分析Monkey日志結果:存在異常日志,請手工再仔細檢查!
ECHO.
) ELSE (
ECHO.[ INFO ] 分析Monkey日志結果:正常
ECHO.
)
ECHO.
ECHO.[ EXIT ] 按任意鍵關閉窗口...
PAUSE>nul |
DOS版本自動化信息收集:
@ECHO OFF
ECHO.:::::::::::::::::::::::::::::::::::::::::::::::::
ECHO.:: Monkey測試 ::
ECHO.:: 作者:Findyou ::
ECHO.:: 版本 V1.0.1 ::
ECHO.:: 時間:2014.08.25 ::
ECHO.:::::::::::::::::::::::::::::::::::::::::::::::::
IF NOT EXIST %~dp0\config.conf GOTO EXIT
ECHO.[ INFO ] 准備Monkey測試
ECHO.[ INFO ] 讀取config.conf中信息
REM 從配置文件中獲得包名
FOR /F "tokens=1,2 delims==" %%a in (config.conf) do (
IF %%a == packageName SET packageName=%%b
IF %%a == appEnName SET appEnName=%%b
IF %%a == appversion SET appversion=%%b
)
REM 獲取日期,格式為:20140808
SET c_date=%date:~0,4%%date:~5,2%%date:~8,2%
REM 獲取得小時,格式為:24小時制,10點前補0
SET c_time=%time:~0,2%
IF /i %c_time% LSS 10 (
SET c_time=0%time:~1,1%
)
REM 組合小時、分、秒,格式為: 131420
SET c_time=%c_time%%time:~3,2%%time:~6,2%
REM 將當運行時間點做為日志文件名
SET logfilename=%c_date%%c_time%
REM 創建當天日期目錄及測試APP日志保存目錄
IF NOT EXIST %~dp0\%c_date% md %~dp0\%c_date%
SET logdir="%~dp0\%c_date%\%appEnName%%appversion%"
IF NOT EXIST %logdir% (
ECHO.[ Exec ] 創建目錄:%c_date%\%appEnName%%appversion%
md %logdir%
)
REM 獲得手機信息,顯示並保存
adb shell cat /system/build.prop>phone.info
FOR /F "tokens=1,2 delims==" %%a in (phone.info) do (
IF %%a == ro.build.version.release SET androidOS=%%b
IF %%a == ro.product.model SET model=%%b
IF %%a == ro.product.brand SET brand=%%b
)
del /a/f/q phone.info
ECHO.[ INFO ] 讀取Phone信息
ECHO. 手機品牌: %brand%
ECHO. 手機型號: %model%
ECHO. 系統版本: Android %androidOS%
ECHO.Phone信息>"%logdir%\%logfilename%_%model%.txt"
ECHO.手機品牌: %brand%>>"%logdir%\%logfilename%_%model%.txt"
ECHO.手機型號: %model%>>"%logdir%\%logfilename%_%model%.txt"
ECHO.系統版本: Android %androidOS%>>"%logdir%\%logfilename%_%model%.txt"
ECHO.
ECHO.[ Exec ] 使用Logcat清空Phone中log
adb logcat -c
REM ECHO.[ INFO ] 暫停2秒...
ping -n 2 127.0.0.1>nul
ECHO.
ECHO.[ INFO ] 開始執行Monkey命令
REM ECHO.[ INFO ] 強制關閉准備測試的APP
adb shell am force-stop %packageName%
:::::::::::::::::Monkey測試命令::::::::::::::::::::::::
::::::::::::修改策略請僅在此區域內修改:::::::::::::::::
ECHO.[ Exec ] adb shell monkey -p %packageName% -s %c_time% --throttle 500 -v -v -v 10000
adb shell monkey -p %packageName% -s %c_time% --throttle 500 -v -v -v 10000>%logdir%\%logfilename%_monkey.log
::::::::::::修改策略請僅在此區域內修改:::::::::::::::::
::::::::::::::::::::::END::::::::::::::::::::::::::::::
ECHO.[ INFO ] 執行Monkey命令結束
ECHO.
ECHO.[ Exce ] 手機截屏
adb shell screencap -p /sdcard/monkey_run_end.png
ECHO.[ INFO ] 拷貝截屏圖片至電腦
adb pull /sdcard/monkey_run_end.png %logdir%
cd %logdir%
ren monkey_run_end.png %logfilename%.png
ECHO.
ECHO.[ Exec ] 使用Logcat導出日志
adb logcat -d >%logdir%\%logfilename%_logcat.log
REM ECHO.
REM ECHO.[ Exec ] 導出traces文件
REM adb shell cat /data/anr/traces.txt>%logfilename%_traces.log
REM 待擴展,上傳日志至服務器
:EXIT
ECHO.
ECHO.[ INFO ] 請按任意鍵關閉窗口... PAUSE>nul |
來自 <http://www.cnblogs.com/findyou/p/4106285.html>
Python版本的封裝:
導出日志與獲取命令:
#coding:utf-8
import sys sys.path.append("..")
import until.Get_FileInfo as Get_FileInfo
''' Created on 2016年4月1日
@author: lyz
備注:用於生成Monkey指令 '''
class Get_MonkeyCmd(): ''' example = "adb shell monkey -p com.nyts.sport --pct-touch 30 --pct-trackball 0 --pct-nav 0 --pct-majornav 20 --pct-appswitch 10 --pct-anyevent 10 -s 12867 -v --throttle 300 20000 > monkeytest.txt" ''' ''' Created on 2016年4月1日 @author: lyz 備注:導出日志文件 ''' def _out_log(self,time): log_out_str = " > ../../report/monkeyreport/" + time + ".txt" return log_out_str
''' Created on 2016年4月1日 @author: lyz 備注:獲取monkey命令 ''' def get_Cmd(self,time): monkey_str = "adb shell monkey " parama = Get_FileInfo.Get_FileInfo().get_ConfigString("monkey", "monkey_para") logpath = self._out_log(time) cmd = monkey_str + parama + logpath return cmd
if __name__ == "__main__": result = Get_MonkeyCmd().get_Cmd("888") print (result) |
Monkey執行:
#coding:utf-8
import sys sys.path.append("..")
import os import subprocess import datetime
import until.Get_MonkeyCmd as Get_MonkeyCmd import until.Package_Control as Package_Control import monkeytest.Check_MonkeyReport as Check_MonkeyReport
now = datetime.datetime.now() #時間數組格式 time = now.strftime("%Y%m%d-%H%M%S") #轉化為指定格式
class Monkey_TestRun: ''' Created on 2016年4月1日 @author: lyz 備注:啟動monkey test ''' def monkey_TestRun(self): cmd_str = Get_MonkeyCmd.Get_MonkeyCmd().get_Cmd(time) print ("Monkey 測試腳本為:" + cmd_str) print ("Monkey測試中...請等待...") os.system(cmd_str) print ("Test END! Begin to Check Report!" + time + ".txt")
check = Check_MonkeyReport.Check_MonkeyReport().check_Log(time) if (check == True): print ("Monkey Report 檢查通過,無異常!") else: print ("ERROR:Monkey Report 檢查存在異常,請手動再次檢查確認!")
if __name__ == "__main__": Monkey_TestRun().monkey_TestRun() |
日志檢查:
''' Created on 2016年3月30日
@author: lyz
備注:檢查monkey_report模塊 ''' #coding:utf-8
class Check_MonkeyReport:
''' Created on 2016年4月5日 @author: lyz 備注:檢查是否發生ANR異常(程序卡死5s) ''' def _Get_ANR(self,str_error): contains = str_error.count('ANR') if (contains > 0): print ("找到ANR異常 " + str(contains) + " 處") return False else: return True
''' Created on 2016年4月5日 @author: lyz 備注:檢查是否發生Crash ''' def _Get_CRASH(self,str_error): contains = str_error.count('CRASH') if (contains > 0): print ("找到CRASH異常 " + str(contains) + " 處") return False else: return True
''' Created on 2016年4月5日 @author: lyz 備注:檢查是否發生Exception異常 ''' def _Get_Exception(self,str_error): contains = str_error.count('Exception') if (contains > 0): print ("找到Exception異常 " + str(contains) + " 處") return False else: return True
''' Created on 2016年4月5日 @author: lyz 備注:檢查是否正常結束,Monkey finished字段 ''' def _Get_Finished(self,str_error): contains = str_error.count('Monkey finished') if (contains > 0): print ("測試結束,未發現異常!") return True else: print ("ERROR:Monkey測試異常中斷,請重新測試!") return False
''' Created on 2016年4月5日 @author: lyz 備注:檢查log文件是否存在異常 ''' def check_Log(self,time): file_path = "../../report/monkeyreport/" + time + ".txt" with open(file_path, 'r') as f: str_log = f.read() if (self._Get_ANR(str_log) and self._Get_CRASH(str_log) and self._Get_Exception(str_log) and self._Get_Finished(str_log)): return True else: return False
if __name__ == "__main__": time = "8888" result = Check_MonkeyReport().check_Log(time) print (result)
|
關於不可控的解決方案:
-
禁用導致不可控控件功能(例如需要登錄的功能禁用登出功能)
缺陷:
需要重新打包
相關功能不會覆蓋
-
白名單:
方法一:
#! /usr/bin/env monkeyrunner from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice print "get device" #use commands like device.touch and device.drag to simulate a navigation and open my activity #with your activity opened start your monkey test print "end monkey test" |
方法二:
adb shell monkey -p my.package -c android.intent.category.MONKEY -v 500 |
Monkey的思維拓展:
Monkey的封裝及性能監控:
封裝:可以把獲取包名寫為配置,每次自動執行,報錯后字都手機相關信息
性能監控:結合性能監控工具,在Monkey執行的過程中,同時監控性能,封裝成一個工具。由於Monkey的隨機性,可以定位一部分性能問題。
感謝:
博客:FINDYOU |
|
testhome恆溫 |
testhome社區 |
樂於分享的互聯網人 |
互聯網搜到的文章 |