1、什麼是monkeyrunnerhtml
monkeyrunner工具提供了一個API,使用此API寫出的程序能夠在Android代碼以外控制Android設備和模擬器。經過monkeyrunner,您能夠寫出一個Python程序去安裝一個Android應用程序或測試包,運行它,向它發送模擬擊鍵,截取它的用戶界面圖片,並將截圖存儲於工做站上。monkeyrunner工具的主要設計目的是用於測試功能/框架水平上的應用程序和設備,或用於運行單元測試套件,但您固然也能夠將其用於其它目的。java
2、monkeyrunner工具同Monkey工具的差異android
Monkey:shell
Monkey工具直接運行在設備或模擬器的adb shell中,生成用戶或系統的僞隨機事件流。api
monkeyrunner:框架
monkeyrunner工具則是在工做站上經過API定義的特定命令和事件控制設備或模擬器。ide
3、monkeyrunner的測試類型工具
一、多設備控制:monkeyrunner API能夠跨多個設備或模擬器實施測試套件。您能夠在同一時間接上全部的設備或一次啓動所有模擬器,依據程序依次鏈接到每個,而後運行一個或多個測試。您也能夠用程序啓動一個配置好的模擬器,運行一個或多個測試,而後關閉模擬器。單元測試
二、功能測試: monkeyrunner能夠爲一個應用自動貫徹一次功能測試。您提供按鍵或觸摸事件的輸入數值,而後觀察輸出結果的截屏。學習
三、迴歸測試:monkeyrunner能夠運行某個應用,並將其結果截屏與既定已知正確的結果截屏相比較,以此測試應用的穩定性。
四、可擴展的自動化:因爲monkeyrunner是一個API工具包,您能夠基於Python模塊和程序開發一整套系統,以此來控制Android設備。除了使用monkeyrunner API以外,您還可使用標準的Python os和subprocess模塊來調用Android Debug Bridge這樣的Android工具。
4、運行monkeyrunner
您能夠直接使用一個代碼文件運行monkeyrunner,或者在交互式對話中輸入monkeyrunner語句。不論使用哪一種方式,您都須要調用SDK目錄的tools子目錄下的monkeyrunner命令。若是您提供一個文件名做爲運行參數,則monkeyrunner將視文件內容爲Python程序,並加以運行;不然,它將提供一個交互對話環境。
monkeyrunner的命令語法爲:
monkeyrunner -plugin <plugin_jar> <program_filename> <program_options>
[以上的內容部分摘自互聯網,借鑑前人的總結]
5、實例
我這裏就以sample中的ApiDemos爲例,咱們學習任何同樣東西彷佛均可以有自帶的Sample開始,能夠在開發環境中先將其生成ApiDemos.apk。
前提:已有device鏈接(這裏能夠是真實設備,或者模擬器)
一、 將ApiDemos.apk放在$Android_Root\tools下。
二、 在$Android_Root\tools下新建一個monkeyrunnerprogram.py文件,按照官方的幫助文檔,該文件裏面內容爲:
1 # Imports the monkeyrunner modules used by this program 2 3 from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage 4 5 # Connects to the current device, returning a MonkeyDevice object 6 7 device = MonkeyRunner.waitForConnection() 8 9 # Installs the Android package. Notice that this method returns a boolean, so you can test10 11 # to see if the installation worked.12 13 device.installPackage('./ApiDemos.apk')14 15 16 # Runs the component17 18 device.startActivity(component='com.example.android.apis/.ApiDemos')19 20 21 # Presses the Menu button22 23 device.press('KEYCODE_MENU','DOWN_AND_UP')24 25 26 # Takes a screenshot27 28 result = device.takeSnapshot()29 30 31 # Writes the screenshot to a file32 33 result.writeToFile('./shot1.png','png')
三、 打開命令行轉到Android_Root\tools目錄下運行一下命令:
monkeyrunner monkeyrunnerprogram.py
130215 23:35:19.711:I [main] [com.android.monkeyrunner.MonkeyManager] Monkey Command: wake.
130215 23:35:20.711:I [main] [com.android.monkeyrunner.MonkeyManager] Monkey Command: wake.
130215 23:35:21.711:I [main] [com.android.monkeyrunner.MonkeyManager] Monkey Command: wake.
130215 23:35:22.835:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] Error starting command: monkey --port 12345
130215 23:35:22.835:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice]com.android.ddmlib.ShellCommandUnresponsiveException
130215 23:35:22.835:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] at com.android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.java:408)
130215 23:35:22.835:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] at com.android.ddmlib.Device.executeShellCommand(Device.java:276)
130215 23:35:22.835:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] at com.android.monkeyrunner.adb.AdbMonkeyDevice$1.run(AdbMonkeyDevice.java:89)
130215 23:35:22.835:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] at java.util.concurrent.Executors$RunnableAdapter.call(UnknownSource)
130215 23:35:22.835:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
130215 23:35:22.835:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] at java.util.concurrent.FutureTask.run(Unknown Source)
130215 23:35:22.835:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
130215 23:35:22.835:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] at java.util.concurrent.ThreadPoolExecutor$Worker.run(UnknownSource)
130215 23:35:22.835:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] at java.lang.Thread.run(UnknownSource)
130215 23:35:55.632:I [main] [com.android.monkeyrunner.MonkeyManager] Monkey Command: press KEYCODE_MENU.
130215 23:35:58.311:I [main] [com.android.monkeyrunner.MonkeyManager] Monkey Command: quit.
四、 能夠Android_Root\tools下查看生成的shot1.png的截圖。
6、實例改進
由於ApiDemos首頁上按下MENU鍵沒有菜單出現,爲了更加形象化,在上一個實驗的基礎上繼續試驗一下:
一、 在$Android_Root\tools下新建一個monkeyrunnerprogram1.py文件,裏面內容爲:
1 # Imports the monkeyrunner modules used by this program 2 3 from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage 4 5 # Connects to the current device, returning a MonkeyDevice object 6 7 device = MonkeyRunner.waitForConnection() 8 9 # Takes a screenshot10 11 result = device.takeSnapshot()12 13 # Writes the screenshot to a file14 15 result.writeToFile('./shotbegin.png','png')16 17 # Presses the Down button18 #這裏是咱們加入的主要內容 19 device.press('KEYCODE_DPAD_DOWN','DOWN_AND_UP')20 21 device.press('KEYCODE_DPAD_DOWN','DOWN_AND_UP')22 23 device.press('KEYCODE_DPAD_DOWN','DOWN_AND_UP')24 25 device.press('KEYCODE_DPAD_DOWN','DOWN_AND_UP')26 27 device.press('KEYCODE_DPAD_DOWN','DOWN_AND_UP')28 29 # Takes a screenshot30 31 result = device.takeSnapshot()32 33 # Writes the screenshot to a file34 35 result.writeToFile('./shotend.png','png')
二、 將畫面定位在Apidemos的首頁,此時光標定位在第一行。
三、 在$Android_Root\tools目錄下運行一下命令:
monkeyrunner monkeyrunnerprogram1.py
四、在運行過程當中咱們能夠看見光標不斷向下移動,而且能夠在當前目錄下咱們自定義的截圖:
運行前:shotbegin.png
運行後,shotend.png(在代碼中進行了5次KEYCODE_DPAD_DOWN操做)
參考資料:
http://developer.android.com/guide/developing/tools/monkeyrunner_concepts.html