天天看點

android實用測試方法之Monkey與MonkeyRunner前言Android UI 測試懶人第一:胡亂的按鍵,交給電腦搞定MonkeyRunnermonkeyRunner 的記錄和回放

本人比較懶,但是,研究如何讓人變懶,卻很積極…最新版的android SDK 4.0 ,monkey和monkeyRunner,變化很大…大到預設是運作失敗的…囧,雖然,monkey和monkeyrunner目前有些不完善,但是,足以應付我們的使用需要.(最新的R15已經解決了這個問題更新真快…)

有時候,我們要折騰一下程式,健壯不健壯,然後,找個上幼稚園的的弟弟/妹妹,把手機交給他/她,讓他/她胡亂的按,看你的程式能不能接受這樣的折騰,但是,我們身邊不可能都有正太和蘿莉,也不能保證他們拿到手機以後不是測試軟體的健壯性,反而測試你的手機經不經摔,這與我們的期望差太遠了…畢竟咱們是來軟的不是來硬的…

當然,這世界牛人一把把的,然後,google公司考慮到我們的需要,把找個由某個牛人寫的程式,內建到了比較新版本的SDK R8(即 android 2.2以後),然後,就有了下文

Monkey的智力就是一個三歲小孩的水準,是以,使用起來也是非常簡單,當然,也做不了什麼複雜的東西

<a target="_blank" href="http://blog.51cto.com/attachment/201202/211414881.jpg"></a>

詳細的monkey介紹,和options的參數請檢視

<a href="http://developer.android.com/guide/developing/tools/monkey.html">http://developer.android.com/guide/developing/tools/monkey.html</a>

這裡就不重複造輪子了…

執行個體:

我們驗證程式在随機1000次事件中,能不能正常運作下去

-v 為 verbose的縮寫,就是詳細輸出事件等級,這個3個v就是輸出等級1至3的所有事件,然後再使用管道指令将輸出結果放到一個文本裡面友善檢視.接下來就是看你的程式能不能在這樣的折騰下堅持下去了.

<a target="_blank" href="http://blog.51cto.com/attachment/201202/211421990.png"></a>

以上截個圖看看吧

------------------------------以下為折騰星人研究參考資料------------------------------

然後,補充一下官方文檔并沒有更新的參數…不信你自己對照着來看,如果,你看到時候,官方更新了我說的這個,希望能回複我一下,讓我更新一下…

主要多了兩個參數:

<a target="_blank" href="http://blog.51cto.com/attachment/201202/211428484.jpg"></a>

這裡我貼一個,國外有人用本地指定scriptfile成功的使用

I am trying to do 2 things with monkey

1. Execute a script with a command like

adb shell monkey -p MY_PACKAGE --setup scriptfile -f /sdcard/ mon_script1.txt 1

where mon_script.txt contains a few touch commands. After I execute this, I see nothing happening on the screen. It even does not give me the "Number of events injected message". I have verified that my touch co-ordinates fall over actual UI elements.

This is the script file I am using

tap 79 29 tap 100 100 tap 200 200 tap 300 300 quit

2. Execute Monkey Network control to type commands individually. I start up monkey to listen to a port and use PuTTY to send commands. I get "OK" return messages, but nothing happens on the screen.

Whenever I use monkey in the random mode, I see interaction on the screen. But I need to get one of the above 2 methods to work. I have seen the sources of monkey and nothing seems to be wrong. Has anyone used monkey in the above described way? If so, please tell me what I am doing wrong.

使用遠端monkey 的代碼模闆

然後重定向我們的模拟器端口

然後telnet 的我們的模拟器

接着telnet成功以後據說可以這樣

tap 150 200

----以上代碼來源于Android application Test Guide 書中

然後,就可以看到我們控制UI事件了,可惜的是,我怎麼測試都不能成功…

目前看來,monkey這個程式其實并不完善,有些功能連官方文檔都還沒更新,不過,作為折騰應用的使用還是足夠的,看着自己的程式在模拟器中不斷的被折磨…接下來要講就是Monkey的進化---&gt;MonkeyRunner

如果,把現階段的monkey比做是幼稚園的小孩,那麼monkeyrunner就是一個國中生了…它支援,自己編寫插件,控制事件,随時截圖,簡而言之,任何你在模拟器/裝置中能幹的事情,MonkeyRunner都能幹,而且還可以記錄和回放!!!

具體介紹…看官方文檔.這裡還是不重複造輪子

<a href="http://developer.android.com/guide/developing/tools/monkeyrunner_concepts.html">http://developer.android.com/guide/developing/tools/monkeyrunner_concepts.html</a>

注意:android sdk r14并沒有把一個關鍵的jar包放lib目錄中,是以,将無法運作,…然後請将SDK TOOLS 直接更新到最新的R15

下面提供一些常用的腳本,自己看着來改吧..

monkey_recorder.py

monkey_placback.py

help.py

monkeyrunner_py腳本.rar

雖然,少了些東西,但是,并不影響我們大部分的需要.接下來用一段典型的monkeyRunner代碼講解!

注意!如果monkeyrunner腳本檔案要使用中文,記得格式儲存為utf8,不然會ASCNII(忘了怎麼拼寫了..)無法支援錯誤

#導入我們需要用到的包和類并且起别名  

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 &gt;&gt; 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截圖  

result = device.takeSnapshot()  

#save to file 儲存到檔案  

result.writeToFile('takeSnapshot\\result1.png','png'); 

<a target="_blank" href="http://blog.51cto.com/attachment/201202/211703157.png"></a>

以上代碼就是用monkeyrunner 實作操作特定操作以後,并且截圖的功能,看上去貌似挺麻煩的…如果你有很多裝置要一起測試,你就會發現以上代碼是多麼爽丫丫的事情.這個腳本的實質就是一個python腳本,懂點,python的朋友,可以利用這個實作非常強悍的功能.這裡就打住了,各位想到什麼好玩,實用的記得回複一下…大家一起交流.

前面講的都是一些在指令行上的操作,我可記不住那麼多的指令操作,我可不知道,我點選的這個點的坐标是多少,我多麼希望,我能夠在可視化界面裡面講我的操作記錄下來,然後,直接重新播放,就像宏一樣,我可以很高興的告訴你,MonkeyRunner有這個功能實作起來也非常簡單,我提供的打封包件中有一個,monkey_recorder.py,直接在指令行中打上:

monkeyrunner monkey_recorder.py 

<a target="_blank" href="http://blog.51cto.com/attachment/201202/211436555.png"></a>

例如我們删掉我們剛才的asd字元串它就會記錄下我們所有的操作!,就會看到如上截圖!!!

<a target="_blank" href="http://blog.51cto.com/attachment/201202/211444930.jpg"></a>

接下來運作我們的儲存的腳本,然後,你就看到模拟器,進行你剛才一樣的操作

monkeyrunner monkey_playback.py monkey_test.mr 

打開我們的檔案可以看到其實就是一些monkeyrunner的一些腳本

TOUCH|{'x':329,'y':132,'type':'downAndUp',} 

TOUCH|{'x':100,'y':100,'type':'downAndUp',} 

TOUCH|{'x':296,'y':407,'type':'downAndUp',} 

TOUCH|{'x':351,'y':227,'type':'downAndUp',}

當然,有界面為什麼不用呢~~~呵呵~

補充一點:如果我們要進行多裝置測試怎麼辦呢?

我們可以打開monkey_playback.py檔案

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() 

至此,monkeyrunner的常用方式就這樣完了,這裡不打算說怎麼編寫一個自己的monkeyrunner插件,因為,我覺得我以上介紹的功能在實際開發中基本夠用,而且,monkeyrunner估計,在下一個版本中會有一些更新,有興趣的同學,自己查閱官方文檔,當然,也可以聯系本人…

本文轉自 liam2199 部落格,原文連結:   http://blog.51cto.com/youxilua/772666如需轉載請自行聯系原作者

繼續閱讀