Android自動(dòng)測(cè)試之monkeyrunner工具
前言:
最近開(kāi)始研究Android自動(dòng)化測(cè)試方法,對(duì)其中的一些工具、方法和框架做了一些簡(jiǎn)單的整理,其中包括android測(cè)試框架、CTS、Monkey、Monkeyrunner、benchmark、其它test tool等等。因接觸時(shí)間很短,很多地方有不足之處,希望能和大家多多交流。
一、什么是monkeyrunner
monkeyrunner工具提供了一個(gè)API,使用此API寫(xiě)出的程序可以在Android代碼之外控制Android設(shè)備和模擬器。通過(guò)monkeyrunner,您可以寫(xiě)出一個(gè)Python程序去安裝一個(gè)Android應(yīng)用程序或測(cè)試包,運(yùn)行它,向它發(fā)送模擬擊鍵,截取它的用戶(hù)界面圖片,并將截圖存儲(chǔ)于工作站上。monkeyrunner工具的主要設(shè)計(jì)目的是用于測(cè)試功能/框架水平上的應(yīng)用程序和設(shè)備,或用于運(yùn)行單元測(cè)試套件,但您當(dāng)然也可以將其用于其它目的。
二、monkeyrunner工具同Monkey工具的差別
Monkey:
Monkey工具直接運(yùn)行在設(shè)備或模擬器的adb shell中,生成用戶(hù)或系統(tǒng)的偽隨機(jī)事件流。
monkeyrunner:
monkeyrunner工具則是在工作站上通過(guò)API定義的特定命令和事件控制設(shè)備或模擬器。
三、monkeyrunner的測(cè)試類(lèi)型
1、多設(shè)備控制:monkeyrunner API可以跨多個(gè)設(shè)備或模擬器實(shí)施測(cè)試套件。您可以在同一時(shí)間接上所有的設(shè)備或一次啟動(dòng)全部模擬器(或統(tǒng)統(tǒng)一起),依據(jù)程序依次連接到每一個(gè),然后運(yùn)行一個(gè)或多個(gè)測(cè)試。您也可以用程序啟動(dòng)一個(gè)配置好的模擬器,運(yùn)行一個(gè)或多個(gè)測(cè)試,然后關(guān)閉模擬器。
2、 功能測(cè)試: monkeyrunner可以為一個(gè)應(yīng)用自動(dòng)貫徹一次功能測(cè)試。您提供按鍵或觸摸事件的輸入數(shù)值,然后觀察輸出結(jié)果的截屏。
3、 回歸測(cè)試:monkeyrunner可以運(yùn)行某個(gè)應(yīng)用,并將其結(jié)果截屏與既定已知正確的結(jié)果截屏相比較,以此測(cè)試應(yīng)用的穩(wěn)定性。
4、 可擴(kuò)展的自動(dòng)化:由于monkeyrunner是一個(gè)API工具包,您可以基于Python模塊和程序開(kāi)發(fā)一整套系統(tǒng),以此來(lái)控制Android設(shè)備。除了使用monkeyrunner API之外,您還可以使用標(biāo)準(zhǔn)的Python os和subprocess模塊來(lái)調(diào)用Android Debug Bridge這樣的Android工具。
四、運(yùn)行monkeyrunner
您可以直接使用一個(gè)代碼文件運(yùn)行monkeyrunner,抑或在交互式對(duì)話(huà)中輸入monkeyrunner語(yǔ)句。不論使用哪種方式,您都需要調(diào)用SDK目錄的tools子目錄下的monkeyrunner命令。如果您提供一個(gè)文件名作為運(yùn)行參數(shù),則monkeyrunner將視文件內(nèi)容為Python程序,并加以運(yùn)行;否則,它將提供一個(gè)交互對(duì)話(huà)環(huán)境。
monkeyrunner的命令語(yǔ)法為:
monkeyrunner -plugin <plugin_jar> <program_filename> <program_options>
五、實(shí)例
以sample中的ApiDemos為例,先將其生成ApiDemos.apk。
前提:已有device連接
1、 將ApiDemos.apk放在$Android_Root\tools下。
2、 在$Android_Root\tools下新建一個(gè)monkeyrunnerprogram.py文件,里面內(nèi)容為:
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 test 10 11 # to see if the installation worked. 12 13 device.installPackage('./ApiDemos.apk') 14 15 16 # Runs the component 17 18 device.startActivity(component='com.example.android.apis/.ApiDemos') 19 20 21 # Presses the Menu button 22 23 device.press('KEYCODE_MENU','DOWN_AND_UP') 24 25 26 # Takes a screenshot 27 28 result = device.takeSnapshot() 29 30 31 # Writes the screenshot to a file 32 33 result.writeToFile('./shot1.png','png') |
注意:SDK上的例子有些錯(cuò)誤,不可直接復(fù)制,否則執(zhí)行命令時(shí)會(huì)發(fā)生錯(cuò)誤。具體可與我的上面這段代碼對(duì)照。
3、 打開(kāi)命令行轉(zhuǎn)到Android_Root\tools目錄下運(yùn)行一下命令:
monkeyrunner monkeyrunnerprogram.py 110307 15:33:19.625:I [main] [com.android.monkeyrunner.MonkeyManager] Monkey Command: wake. 110307 15:33:20.625:I [main] [com.android.monkeyrunner.MonkeyManager] Monkey Command: wake. 110307 15:33:21.625:I [main] [com.android.monkeyrunner.MonkeyManager] Monkey Command: wake. 110307 15:33:22.718:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] Error starting command: monkey --port 12345 110307 15:33:22.718:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice]com.android.ddmlib.ShellCommandUnresponsiveException 110307 15:33:22.718:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] at com.android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.java:408) 110307 15:33:22.718:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] at com.android.ddmlib.Device.executeShellCommand(Device.java:276) 110307 15:33:22.718:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] at com.android.monkeyrunner.adb.AdbMonkeyDevice$1.run(AdbMonkeyDevice.java:89) 110307 15:33:22.718:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] at java.util.concurrent.Executors$RunnableAdapter.call(UnknownSource) 110307 15:33:22.718:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) 110307 15:33:22.718:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] at java.util.concurrent.FutureTask.run(Unknown Source) 110307 15:33:22.718:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) 110307 15:33:22.718:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] at java.util.concurrent.ThreadPoolExecutor$Worker.run(UnknownSource) 110307 15:33:22.718:S [pool-1-thread-1] [com.android.monkeyrunner.adb.AdbMonkeyDevice] at java.lang.Thread.run(UnknownSource) 110307 15:33:57.437:I [main] [com.android.monkeyrunner.MonkeyManager] Monkey Command: press KEYCODE_MENU. 110307 15:33:59.171:I [main] [com.android.monkeyrunner.MonkeyManager] Monkey Command: quit. |
注:里面exception的提示我們可以忽略,因?yàn)槲覀兛梢钥匆?jiàn) Monkey Command: press KEYCODE_MENU已經(jīng)執(zhí)行成功。
4、 可以Android_Root\tools下查看生成的shot1.png的截圖。
六、實(shí)例擴(kuò)展
因?yàn)锳piDemos首頁(yè)上按下MENU鍵沒(méi)有菜單出現(xiàn),為了更加形象化,在實(shí)例五的基礎(chǔ)上繼續(xù)試驗(yàn):
1、 在$Android_Root\tools下新建一個(gè)monkeyrunnerprogram1.py文件,里面內(nèi)容為:
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 screenshot 10 11 result = device.takeSnapshot() 12 13 # Writes the screenshot to a file 14 15 result.writeToFile('./shotbegin.png','png') 16 17 # Presses the Down button 18 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 screenshot 30 31 result = device.takeSnapshot() 32 33 # Writes the screenshot to a file 34 35 result.writeToFile('./shotend.png','png') |
2、 將畫(huà)面定位在Apidemos的首頁(yè),并將光標(biāo)定位在第一項(xiàng)上。
3、 在$Android_Root\tools目錄下運(yùn)行一下命令:
monkeyrunner monkeyrunnerprogram1.py
4、在運(yùn)行過(guò)程中我們可以看見(jiàn)光標(biāo)不斷向下移動(dòng),并且可以在當(dāng)前目錄下我們自定義的截圖:
運(yùn)行前:
運(yùn)行后(做了五次下移操作):
posted on 2014-06-10 09:45 順其自然EVO 閱讀(183) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): android