之前的幾篇文章,我們分別介紹了monkey,junit, Robotium,以及基於junit的android測試架構進行介紹,本篇文章我們將對monkeyRunner 進行介紹。
1、什麼是monkeyrunner
monkeyrunner工具提供了一個API,使用此API寫出的程式可以在Android代碼之外控制Android裝置和模擬器。通過monkeyrunner,您可以寫出一個Python程式去安裝一個Android應用程式或測試包,運行它,向它發送類比擊鍵,截取它的使用者介面圖片,並將儲存於工作站上。monkeyrunner工具的主要設計目的是用於測試功能/架構水平上的應用程式和裝置,或用於運行單元測試套件,但您當然也可以將其用於其它目的。
2、monkeyrunner工具同Monkey工具的差別
Monkey:
Monkey工具直接運行在裝置或模擬器的adb shell中,產生使用者或系統的偽隨機事件流。
monkeyrunner:
monkeyrunner工具則是在工作站上通過API定義的特定命令和事件控制裝置或模擬器。
3、monkeyrunner的測試類型
- 1、多裝置控制: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、執行個體1
5.1 簡單一實例以sample中的ApiDemos為例,先將其產生ApiDemos.apk。
前提:已有device串連
1)、 將ApiDemos.apk放在$Android_Root\tools下。
2)、 在$Android_Root\tools下建立一個monkeyrunnerprogram.py檔案,裡面內容為:
# Imports the monkeyrunner modules used by this programfrom com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage# Connects to the current device, returning a MonkeyDevice objectdevice = MonkeyRunner.waitForConnection()# Installs the Android package. Notice that this method returns a boolean, so you can test# to see if the installation worked.device.installPackage('./ApiDemos.apk')# Runs the componentdevice.startActivity(component='com.example.android.apis/.ApiDemos')# Presses the Menu buttondevice.press('KEYCODE_MENU','DOWN_AND_UP')# Takes a screenshotresult = device.takeSnapshot()# Writes the screenshot to a fileresult.writeToFile('./shot1.png','png')
注意:SDK上的例子有些錯誤,不可直接複製,否則執行命令時會發生錯誤。具體可與我的上面這段代碼對照。
3)、 開啟命令列轉到Android_Root\tools目錄下運行一下命令:
monkeyrunner monkeyrunnerprogram.py若無錯誤,則運行完成以後,$Android_Root\tools目錄下會產生shot1.png檔案。注意,在運行過程中,若沒有錯誤,命令列沒有任何輸出。5.2 擴充執行個體因為ApiDemos首頁上按下MENU鍵沒有菜單出現,為了更加形象化,在執行個體五的基礎上繼續實驗:
1)、 在$Android_Root\tools下建立一個monkeyrunnerprogram1.py檔案,裡面內容為:
# Imports the monkeyrunner modules used by this program from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage# Connects to the current device, returning a MonkeyDevice objectdevice = MonkeyRunner.waitForConnection()# Takes a screenshotresult = device.takeSnapshot()# Writes the screenshot to a file result.writeToFile('./shotbegin.png','png')# Presses the Down buttondevice.press('KEYCODE_DPAD_DOWN','DOWN_AND_UP')device.press('KEYCODE_DPAD_DOWN','DOWN_AND_UP')device.press('KEYCODE_DPAD_DOWN','DOWN_AND_UP')device.press('KEYCODE_DPAD_DOWN','DOWN_AND_UP')device.press('KEYCODE_DPAD_DOWN','DOWN_AND_UP')# Takes a screenshotresult = device.takeSnapshot()# Writes the screenshot to a fileresult.writeToFile('./shotend.png','png')
2)、將畫面定位在Apidemos的首頁,並將游標定位在第一項上。
3)、$Android_Root\tools目錄下運行一下命令:
monkeyrunner monkeyrunnerprogram1.py
4)、在運行過程中我們可以看見游標不斷向下移動,並且可以在目前的目錄下我們自訂的:
運行前:shotbegin.png6、擴充應用執行個體下面提供一些常用的指令碼,自己看著來改吧..
monkey_recorder.py
monkey_placback.py
help.py具體為:monkeyrunner_py指令碼.rar雖然,少了些東西,但是,並不影響我們大部分的需要.接下來用一段典型的monkeyRunner代碼講解!
注意!如果monkeyrunner指令檔要使用中文,記得格式儲存為utf8,不然會ASCNII(忘了怎麼拼字了..)無法支援錯誤6.1 takescreen.py檔案takescreen.py
#匯入我們需要用到的包和類並且起別名import sysfrom com.android.monkeyrunner import MonkeyRunner as mrfrom com.android.monkeyrunner import MonkeyDevice as mdfrom com.android.monkeyrunner import MonkeyImage as mi#connect device 串連裝置#第一個參數為等待串連裝置時間#第二個參數為具體串連的裝置device = mr.waitForConnection()if not device: print >> sys.stderr,"fail" sys.exit(1)#定義要啟動的ActivitycomponentName='com.example.android.notepad/.NotesList'#啟動特定的Activitydevice.startActivity(component=componentName)mr.sleep(3.0)#do someting 進行我們的操作#輸入 a s d#device.press('KEYCODE_HOME')#device.touch(418, 736,'DOWN_AND_UP')#mr.sleep(3.0)#device.touch(180, 520,'DOWN_AND_UP')#mr.sleep(3.0)device.press('KEYCODE_MENU')mr.sleep(3.0)device.touch(243, 745,'DOWN_AND_UP')mr.sleep(3.0)device.type('woaini')device.press('KEYCODE_ENTER')mr.sleep(3.0)device.type(',')device.press('KEYCODE_ENTER')mr.sleep(3.0)device.type('yiwen')device.press('KEYCODE_ENTER')mr.sleep(3.0)device.press('KEYCODE_BACK')#device.press('KEYCODE_HOME')#device.type('asd')#輸入斷行符號#device.press('KEYCODE_ENTER')#return keyboard 點擊返回用於取消等下看到的下方的白條#device.press('KEYCODE_BACK')#------#takeSnapshotmr.sleep(3.0)result = device.takeSnapshot() #save to file 儲存到檔案result.writeToFile('result1.png','png');
這裡用到的notelist執行個體類似於android提供的notepad執行個體。
其運行結果為(圖result1.png):
6.2 monkeyRunner 的記錄和回放 前面講的都是一些在命令列上的操作,我可記不住那麼多的指令操作,我可不知道,我點擊的這個點的座標是多少,我多麼希望,我能夠在可視化介面裡面講我的操作記錄下來,然後,直接重新播放,就像宏一樣,我可以很高興的告訴你,MonkeyRunner有這個功能實現起來也非常簡單,我提供的打包檔案中有一個,monkey_recorder.py,直接在命令列中打上:monkeyrunner monkey_recorder.py其中手機螢幕部分,與當前串連的手機裝置的螢幕顯示是一致的。對其中指令碼顯示的一些說明:接下來運行我們的儲存的指令碼,然後,你就看到模擬器,進行你剛才一樣的操作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':296,'y':407,'type':'downAndUp',} TOUCH|{'x':296,'y':407,'type':'downAndUp',} TOUCH|{'x':296,'y':407,'type':'downAndUp',} TOUCH|{'x':351,'y':227,'type':'downAndUp',}
當然,有介面為什麼不用呢~~~呵呵~
補充一點:如果我們要進行多裝置測試怎麼辦呢?
我們可以開啟monkey_playback.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.import sysfrom 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_py指令碼.rar”中的所有源碼,以及其中monkeyRunner各個類的說明檔案。 另外Google原始說明檔案為:http://developer.android.com/guide/developing/tools/monkeyrunner_concepts.html,有興趣可以看看。源碼下載:http://download.csdn.net/detail/xianming01/4253617參考文獻:Android自動化的測試之monkeyrunner工具
android實用測試方法之Monkey與MonkeyRunner