1. 程式人生 > >MonkeyRunner 錄製與回放

MonkeyRunner 錄製與回放

MonkeyRunner

什麼是monkeyrunner

monkeyrunner工具提供了一個API,使用此API寫出的程式可以在Android程式碼之外控制Android裝置和模擬器。通過monkeyrunner,您可以寫出一個Python程式去安裝一個Android應用程式或測試包,執行它,向它傳送模擬擊鍵,擷取它的使用者介面圖片,並將截圖儲存於工作站上。monkeyrunner工具的主要設計目的是用於測試功能/框架水平上的應用程式和裝置,或用於執行單元測試套件。

monkeyrunner同monkey的區別

Monkey工具直接執行在裝置或模擬器的adb shell中,生成使用者或系統的偽隨機事件流。monkeyrunner工具則是在工作站上通過API定義的特定命令和事件控制裝置或模擬器,它支援,自己編寫外掛,控制事件,隨時截圖,簡而言之,任何你在模擬器/裝置中能幹的事情,MonkeyRunner都能幹,而且還可以記錄和回放。

monkeyrunner的測試型別

1、多裝置控制:monkeyrunner API可以跨多個裝置或模擬器實施測試套件。您可以在同一時間接上所有的裝置或一次啟動全部模擬器(或統統一起),依據程式依次連線到每一個,然後執行一個或多個測試。您也可以用程式啟動一個配置好的模擬器,執行一個或多個測試,然後關閉模擬器。

2、 功能測試: monkeyrunner可以為一個應用自動貫徹一次功能測試。您提供按鍵或觸控事件的輸入數值,然後觀察輸出結果的截圖。

3、 迴歸測試:monkeyrunner可以執行某個應用,並將其結果截圖與既定已知正確的結果截圖相比較,以此測試應用的穩定性。

4、 可擴充套件的自動化:由於monkeyrunner是一個API工具包,您可以基於Python模組和程式開發一整套系統,以此來控制Android裝置。除了使用monkeyrunner API之外,您還可以使用標準的Python os和subprocess模組來呼叫Android Debug Bridge這樣的Android工具。

執行monkeyrunner

您可以直接使用一個程式碼檔案執行monkeyrunner,抑或在互動式對話中輸入monkeyrunner語句。不論使用哪種方式,您都需要呼叫SDK目錄的tools子目錄下的monkeyrunner命令。如果您提供一個檔名作為執行引數,則monkeyrunner將視檔案內容為Python程式,並加以執行;否則,它將提供一個互動對話環境。

monkeyrunner基本語法

  1. monkeyrunner -plugin <plugin_jar> <program_filename> <program_options>  
具體介紹…看官方文件(http://developer.android.com/guide/developing/tools/monkeyrunner_concepts.html)

例項

連線真機(模擬器),開啟CMD,進入:E:\android-sdk-windows\tools資料夾內(裡面有monkeyrunner.bat)

建立一個Python指令碼檔案:testrunner.py,內容如下:

注意!如果monkeyrunner指令碼檔案要使用中文,記得格式儲存為utf8,不然會ASCNII無法支援錯誤

  1. #匯入我們需要用到的包和類並且起別名  
  2. import sys  
  3. from com.android.monkeyrunner import MonkeyRunner as mr  
  4. from com.android.monkeyrunner import MonkeyDevice as md  
  5. from com.android.monkeyrunner import MonkeyImage as mi  
  6. #connect device 連線裝置  
  7. #第一個引數為等待連線裝置時間  
  8. #第二個引數為具體連線的裝置  
  9. device = mr.waitForConnection(1.0,'e0d98451')  
  10. if not device:  
  11.     print >> sys.stderr,"fail"
  12.     sys.exit(1)  
  13. #定義要啟動的Activity  
  14. componentName='com.example.simulate/.ShellActivity'
  15. #啟動特定的Activity  
  16. device.startActivity(component=componentName)  
  17. mr.sleep(3.0)  
  18. #do someting 進行我們的操作  
  19. #輸入 helloworld  
  20. device.type('helloworld')  
  21. #輸入回車  
  22. device.press('KEYCODE_ENTER')  
  23. #return keyboard  
  24. #device.press('KEYCODE_BACK')  
  25. #------  
  26. #takeSnapshot截圖  
  27. mr.sleep(3.0)  
  28. result = device.takeSnapshot()  
  29. #save to file 儲存到檔案  
  30. result.writeToFile('./shot1.png','png');  


接下來命令列輸入:

  1. monkeyrunner testrunner.py  

這是一個小的指令碼檔案,主要是啟動com.example.simulate包名下的ShellActivity介面,接下來按下Enter按鈕,最後截圖,並儲存在當前目錄下為shot1.png,可以在toosl資料夾下檢視。


這個指令碼的實質就是一個python指令碼,懂python的朋友,可以利用這個實現非常強悍的功能~~~~~~~~~~~~~~~~~~~~~~~~

monkeyRunner 的記錄和回放

這才是真正實用的功能,直接看程式碼,建立一個recoder.py:

  1. #!/usr/bin/env monkeyrunner  
  2. # Copyright 2010, The Android Open Source Project  
  3. #  
  4. # Licensed under the Apache License, Version 2.0 (the "License");  
  5. # you may not use this file except in compliance with the License.  
  6. # You may obtain a copy of the License at  
  7. #  
  8. #     http://www.apache.org/licenses/LICENSE-2.0
  9. #  
  10. # Unless required by applicable law or agreed to in writing, software  
  11. # distributed under the License is distributed on an "AS IS" BASIS,  
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
  13. # See the License for the specific language governing permissions and  
  14. # limitations under the License.  
  15. from com.android.monkeyrunner import MonkeyRunner as mr  
  16. from com.android.monkeyrunner.recorder import MonkeyRecorder as recorder  
  17. device = mr.waitForConnection()  
  18. recorder.start(device)  

命令列下執行:
  1. monkeyrunner monkey_recorder.py  

這時會彈出這樣的介面:


按鈕以及一些功能說明:

Button Description
Wait 等待時間
Press a Button 傳送,MENU,HOME,or SEARCH 按鈕.Press,Down,or Up事件
Type Something 傳送一些字串
Fling 用來操作虛擬鍵盤 
image
Export Action 將我們的指令碼匯出來
Refresh Display 重新整理當前介面

自己隨心所以建立一些事件指令碼,想做什麼就可以做什麼,通過MonkeyRecorder這個工具來操作裝置介面,事件編輯完後選擇Export Actions,匯出到我們tools目錄下命名為:action.mr

我們看一下工具生成的action.mr指令碼,如下:

  1. TOUCH|{'x':297,'y':533,'type':'downAndUp',}  
  2. WAIT|{'seconds':2.0,}  
  3. TOUCH|{'x':136,'y':278,'type':'downAndUp',}  
  4. WAIT|{'seconds':2.0,}  
  5. TOUCH|{'x':123,'y':356,'type':'downAndUp',}  
  6. WAIT|{'seconds':10.0,}  
  7. PRESS|{'name':'HOME','type':'downAndUp',}  
  8. WAIT|{'seconds':2.0,}  
  9. TOUCH|{'x':235,'y':720,'type':'downAndUp',}  
  10. WAIT|{'seconds':2.0,}  
  11. TOUCH|{'x':303,'y':630,'type':'downAndUp',}  
  12. WAIT|{'seconds':2.0,}  
  13. TOUCH|{'x':16,'y':71,'type':'downAndUp',}  
  14. WAIT|{'seconds':2.0,}  
  15. TOUCH|{'x':244,'y':735,'type':'downAndUp',}  

然後需要製作一個執行這一系列動作的指令碼:monkey_playback.py,儲存到tools目錄下:

  1. #!/usr/bin/env monkeyrunner  
  2. # Copyright 2010, The Android Open Source Project  
  3. #  
  4. # Licensed under the Apache License, Version 2.0 (the "License");  
  5. # you may not use this file except in compliance with the License.  
  6. # You may obtain a copy of the License at  
  7. #  
  8. #     http://www.apache.org/licenses/LICENSE-2.0
  9. #  
  10. # Unless required by applicable law or agreed to in writing, software  
  11. # distributed under the License is distributed on an "AS IS" BASIS,  
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
  13. # See the License for the specific language governing permissions and  
  14. # limitations under the License.  
  15. import sys  
  16. from com.android.monkeyrunner import MonkeyRunner  
  17. # The format of the file we are parsing is very carfeully constructed.  
  18. # Each line corresponds to a single command.  The line is split into 2
  19. # parts with a | character.  Text to the left of the pipe denotes  
  20. # which command to run.  The text to the right of the pipe is a python  
  21. # dictionary (it can be evaled into existence) that specifies the  
  22. # arguments for the command.  In most cases, this directly maps to the  
  23. # keyword argument dictionary that could be passed to the underlying  
  24. # command.   
  25. # Lookup table to map command strings to functions that implement that  
  26. # command.  
  27. CMD_MAP = {  
  28.     'TOUCH': lambda dev, arg: dev.touch(**arg),  
  29.     'DRAG': lambda dev, arg: dev.drag(**arg),  
  30.     'PRESS': lambda dev, arg: dev.press(**arg),  
  31.     'TYPE': lambda dev, arg: dev.type(**arg),  
  32.     'WAIT': lambda dev, arg: MonkeyRunner.sleep(**arg)  
  33.     }  
  34. # Process a single file for the specified device.  
  35. def process_file(fp, device):  
  36.     for line in fp:  
  37.         (cmd, rest) = line.split('|')  
  38.         try:  
  39.             # Parse the pydict  
  40.             rest = eval(rest)  
  41.         except:  
  42.             print 'unable to parse options'
  43.             continue
  44.         if cmd not in CMD_MAP:  
  45.             print 'unknown command: ' + cmd  
  46.             continue
  47.         CMD_MAP[cmd](device, rest)  
  48. def main():  
  49.     file = sys.argv[1]  
  50.     fp = open(file, 'r')  
  51.     device = MonkeyRunner.waitForConnection()  
  52.     process_file(fp, device)  
  53.     fp.close();  
  54. if __name__ == '__main__':  
  55.     main()  
接下來執行我們的儲存的指令碼,然後,你就看到真機(模擬器),進行你剛才一樣的操作~