monkey 的使用
monkey的簡單操作:
Monkey的智力就是一個三歲小孩的水平,所以,使用起來也是非常簡單,當然,也做不了什麼複雜的東西
adb shell monkey [options] <event-count> |
event-count |
這個是配置monkey的設置, 例如, options是指定啓動那個包,不指定將會隨機啓動所有程序。 event-count是指定隨機事件的執行次數。 |
這個是讓monkey發送多少次事件 |
實例:
我們驗證程序在隨機1000次事件中,能不能正常運行下去:
adb shell monkey -p your.package.name -vvv 1000 > monkey1000.txt
這裏應當注意:
your.package.name --> 就是你要測試的應用的包名;
1000 --> 就是你要執行的次數;
monkey1000.txt --> 你要將執行結果保存到哪裏(要注意的是指明絕對路徑)。
-v 爲 verbose的縮寫,就是詳細輸出事件等級,這個3個v就是輸出等級1至3的所有事件,然後再使用管道命令將輸出結果放到一個文本里面方便查看.接下來就是看你的程序能不能在這樣的折騰下堅持下去了.
以上截個圖看看吧
九個事件及百分比控制
1、九個事件
--pct-touch <percent> 0
調整觸摸事件的百分比(觸摸事件是一個down-up事件,它發生在屏幕上的某單一位置)(——點擊事件,涉及down、up)
--pct-motion <percent> 1
調整動作事件的百分比(動作事件由屏幕上某處的一個down事件、一系列的僞隨機事件和一個up事件組成) (——注:move事件,涉及down、up、move三個事件)
--pct-trackball <percent> 2
調整軌跡事件的百分比(軌跡事件由一個或幾個隨機的移動組成,有時還伴隨有點擊)--(軌跡球)
--pct-nav <percent> 3
調整“基本”導航事件的百分比(導航事件由來自方向輸入設備的up/down/left/right組成)
--pct-majornav <percent> 4
調整“主要”導航事件的百分比(這些導航事件通常引發圖形界面中的動作,如:5-way鍵盤的中間按鍵、回退按鍵、菜單按鍵)
--pct-syskeys <percent> 5
調整“系統”按鍵事件的百分比(這些按鍵通常被保留,由系統使用,如Home、Back、Start Call、End Call及音量控制鍵)
--pct-appswitch <percent> 6
調整啓動Activity的百分比。在隨機間隔裏,Monkey將執行一個startActivity()調用,作爲最大程度覆蓋包中全部Activity的一種方法。(從一個Activity跳轉到另一個Activity)
--pct-flip <percent> 7
調整“鍵盤翻轉”事件的百分比。
--pct-anyevent <percent> 8
調整其它類型事件的百分比。它包羅了所有其它類型的事件,如:按鍵、其它不常用的設備按鈕、等等。
紅色的數字對應下面百分比對應的數字。比如下圖中0:15.0%,表示分配--pct-touch事件15%。測試100次分配15次測試down-up。
2、百分比控制
如果在monkey參數中不指定上述參數,這些動作都是隨機分配的,9個動作其每個動作分配的百分比之和爲100%,我們可以通過添加命令選項來控制每個事件的百分比,進而可以將操作限制在一定的範圍內。
我們先來看一下不加動作百分比控制,系統默認分配事件百分比的情況
命令:adb shell monkey -p com.android.email -vvv 100 結果:
再看一下指定事件,控制事件百分比之後的情況
命令:adb shell monkey -p com.android.email --pct-anyevent 100 -vvv 100
結果:
說明:--pct-anyevent 100 表明pct-anyevent所代表的事件的百分比爲100%。
在monkey測試中常用的命令組合有
1、monkey -p com.yourpackage -v 500 簡單的輸出測試的信息。
2、monkey -p com.yourpackage -v -v -v 500 以深度爲三級輸出測試信息。
3、monkey -p com.yourpackage --port 端口號 -v 爲測試分配一個專用的端口號,不過這個命令只能輸出跳轉的信息及有錯誤時輸出信息。
4、monkey -p com.yourpackage -s 數字 -v 500 爲隨機數的事件序列定一個值,若出現問題下次可以重複同樣的系列進行排錯。
5、monkey -p com.yourpackage -v --throttle 3000 500 爲每一次執行一次有效的事件後休眠3000毫秒。
Moneky Test Log 簡單分析:
/*表示跳轉到com.android.email裏面的Welcome這一個Activity裏。*/
/*允許此Intent跳轉。*/
/*拒絕次Intent跳轉,因爲它是跳轉到非它自己的包的Activity,本測試中是指寫測試它程序所在的包,此跳轉是跳出本程序,進入到zhibo8中。*/
/*發送的一些動作,如點擊按下,點擊放開,移動。 */
/*事件注入次數 100次*/
/*丟棄的,鍵=0,指針=0,軌跡球=0,輕擊=0,翻轉=0。*/
/*網絡統計經過時間爲2556ms,其中0ms是用於在手機上的,2556ms用於無線網絡上,沒有連接的時間爲0ms。*/
/*monkey結束*/
monkey使用時常會遇到的錯誤:
1 error: device not found
如果你用的是模擬器這說明你的模擬器沒有啓動成功,需要重啓模擬器;如果你的是真機測試,只需將USB重插就行了(但要確保開發者模式-->USB調試已開啓)。
然後運行:adb devices 命令行查看是否有設備連接成功。 如下圖:
2 error: more than one device and emulator
錯誤說明是有一個以上的設備和仿真器。這是因爲我啓用了模擬器,同時我也將我的手機通過USB線連接到了電腦。所以這裏存在兩個設備。
不信我們可以試試,運行:adb devices 如下圖:
這種情況下,需要指定連接某一個設備或者模擬器就行了。
命令行運行:adb -s 1494ab93 shell monkey -p com.android.email -vvv 100
-s是關鍵字,當有多臺設備連接時,使用-s指明你測試要使用的設備。如下圖:
monkeyrunner的使用
錄製和回放:
1 將以下代碼存儲爲monkey_recorder.py文件,文件名隨意。此文件用於啓動錄製功能。
#!/usr/bin/env monkeyrunner
# Copyright 2010, The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from com.android.monkeyrunner import MonkeyRunner as mr
from com.android.monkeyrunner.recorder import MonkeyRecorder as recorder
device = mr.waitForConnection()
recorder.start(device)
2 將以下代碼存儲爲recorder_playback.py文件,文件名隨意。此文件用於腳本回放功能。
from com.android.monkeyrunner import MonkeyRunner
CMD_MAP = {
'TOUCH': lambda dev, arg: dev.touch(**arg),
'DRAG': lambda dev, arg: dev.drag(**arg),
'PRESS': lambda dev, arg: dev.press(**arg),
'TYPE': lambda dev, arg: dev.type(**arg),
'WAIT': lambda dev, arg: MonkeyRunner.sleep(**arg)
}
# Process a single file for the specified device.
def process_file(fp, device):
for line in fp:
(cmd, rest) = line.split('|')
try:
# Parse the pydict
rest = eval(rest)
except:
print 'unable to parse options'
continue
if cmd not in CMD_MAP:
print 'unknown command: ' + cmd
continue
CMD_MAP[cmd](device, rest)
def main():
file = sys.argv[1]
device = MonkeyRunner.waitForConnection()
for i in range(1000):
fp = open(file, 'r')
i=i+1
print i
process_file(fp, device)
fp.close();
if __name__ == '__main__':
main()
3 啓動安卓模擬器。
4 打開cmd,輸入命令monkeyrunner (絕對路徑)monkey_recorder.py ,會顯示如下界面:
5 錄製腳本
⑴、錄製功能說明
wait: 用來插入下一次操作的時間間隔,點擊後即可設置時間,單位是秒;
Press a Button:用來確定需要點擊的按鈕,包括menu、home、search,以及對按鈕的press、 down、up屬性(備註:按鈕可以自定義,目前工具提供的只有以上幾個按鍵,其它按鍵需要時,在腳本中可編輯;
Type Something:用來輸入內容到輸入框;
Fling:用來進行拖動操作,可以向上、下、左、右,以及操作的範圍;
Export Actions:用來導出腳本;
Refresh Display:用來刷新手機界面,估計只有在斷開手機後,重新連接時纔會用到。
⑵、開始錄製,例如:錄製一個計算器壓力測試腳本
測試機保持在待機界面,工具同步顯示待機界面,爲保證腳本能更好的運行,一般在每個動作之間建議加一個wait 1秒的動作,點擊wait,輸入1秒
錄製界面如下圖:
錄製完成點擊Export Actions導出腳本,保存爲無後綴文件,如下圖:
將導出腳本文件後綴改爲 .py文件,如下圖:
6 腳本回放
首先我們需要更改回放腳本循環次數,打開recorder_playback.py文件,找到以下語句,其中數據可以更改爲任意你想要執行的次數,修改成功後保存,現在以1000爲例
打開cmd,輸入命令monkeyrunner (絕對路徑)recorder_playback.py(空格)(絕對路徑)test.py,會顯示如下界面:
monkeyrunner多設備測試:
接下來用一段典型的monkeyRunner代碼講解!
注意!如果monkeyrunner腳本文件要使用中文,記得格式保存爲utf8,不然會ASCII無法支持錯誤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#導入我們需要用到的包和類並且起別名 import sys from com.android.monkeyrunner import MonkeyRunner as mr from com.android.monkeyrunner import MonkeyDevice as md from com.android.monkeyrunner import MonkeyImage as mi
#connect device 連接設備 #第一個參數爲等待連接設備時間 #第二個參數爲具體連接的設備 device = mr.waitForConnection(1.0,'emulator-5554') if not device: print >> sys.stderr,"fail" sys.exit(1) #定義要啓動的Activity componentName='kg.monkey/.MonkeyActivity' #啓動特定的Activity device.startActivity(component=componentName) mr.sleep(3.0) #do someting 進行我們的操作 #輸入 a s d device.type('asd') #輸入回車 device.press('KEYCODE_ENTER') #return keyboard 點擊返回用於取消等下看到截圖的下方的白條 #device.press('KEYCODE_BACK') #------ #takeSnapshot截圖 mr.sleep(3.0) result = device.takeSnapshot()
#save to file 保存到文件 result.writeToFile('takeSnapshot\\result1.png','png'); |
以上代碼就是用monkeyrunner 實現操作特定操作以後,並且截圖的功能,看上去貌似挺麻煩的…如果你有很多設備要一起測試,你就會發現以上代碼是多麼爽丫丫的事情.這個腳本的實質就是一個python腳本,懂點,python的朋友,可以利用這個實現非常強悍的功能.
補充一點:如果我們要進行多設備測試怎麼辦呢?
我們可以打開recorder_playback.py文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
import sys from com.android.monkeyrunner import MonkeyRunner
# The format of the file we are parsing is very carfeully constructed. # Each line corresponds to a single command. The line is split into 2 # parts with a | character. Text to the left of the pipe denotes # which command to run. The text to the right of the pipe is a python # dictionary (it can be evaled into existence) that specifies the # arguments for the command. In most cases, this directly maps to the # keyword argument dictionary that could be passed to the underlying # command.
# Lookup table to map command strings to functions that implement that # command. CMD_MAP = { 'TOUCH': lambda dev, arg: dev.touch(**arg), 'DRAG': lambda dev, arg: dev.drag(**arg), 'PRESS': lambda dev, arg: dev.press(**arg), 'TYPE': lambda dev, arg: dev.type(**arg), 'WAIT': lambda dev, arg: MonkeyRunner.sleep(**arg) }
# Process a single file for the specified device. def process_file(fp, device): for line in fp: (cmd, rest) = line.split('|') try: # Parse the pydict rest = eval(rest) except: print 'unable to parse options' continue
if cmd not in CMD_MAP: print 'unknown command: ' + cmd continue
CMD_MAP[cmd](device, rest)
def main(): file = sys.argv[1] fp = open(file, 'r') #在這裏指定你的設備吧 device = MonkeyRunner.waitForConnection()
process_file(fp, device) fp.close();
if __name__ == '__main__': main() |
多設備連接實例
def main():
device1 = MonkeyRunner.waitForConnection(5.0, '1123456789ABCDEF')
if not device1:
print("device1 connection fail")
else:
print("device1 connection success")
device2 = MonkeyRunner.waitForConnection(5.0, '0123456789ABCDEF')
if not device2:
print("device2 connection fail")
else:
print("device2 connection success")
device1.startActivity(component="com.aliyun.wireless.vos.appstore/com.aliyun.wireless.vos.appstore.SlideActivity")
MonkeyRunner.sleep(5)
device2.startActivity(component="com.android.settings/com.android.settings.Settings")
if __name__ == "__main__":
main()
注意:(1)5.0是非常有必要加的,它不是指執行多久,而是多久才執行。