monkeyrunner簡介
①monkeyrunner工具使用Jython,這是一種使用Java編程語言的Python實現。Jython允許monkeyrunner API與Android框架輕松交互。使用Jython可以使用Python語法來訪問API的常量,類和方法。monkeyrunner提供了多個API,通過monkeyrunner API 可以寫一個Python的程序來模擬操作控制Android設備或者Android虛擬機的app,測試其穩定性並通過截屏可以方便地記錄出現的問題。
②monkeyrunner官網對monkeyrunner工具的解釋介紹:
monkeyrunner工具提供了一個API,用於編寫從Android代碼外部控制Android設備或模擬器的程序。使用monkeyrunner,您可以編寫一個Python程序,安裝Android應用程序或測試包,運行它,向其發送擊鍵,截取其用戶界面,並在工作站上存儲屏幕截圖、monkeyrunner工具主要用於測試功能/框架級別的應用程序和設備以及運行單元測試套件,但您可以將其用於其他目的。
③monkeyrunner工具即Android SDK中自帶的工具之一,此工具提供API可控制android設備或模擬器。
④monkeyruuner測試工具的官方網站:monkeyrunner官網
⑤monkeyrunner在Android SDK中的路徑:Andriod_SDK\tools
MonkeyRunner測試工具的獨特功能
①多設備控制:monkeyrunner API可以跨多個安卓設備或安卓模擬器應用一個或多個測試套件。可以物理連接所有安卓設備或啟動所有安卓模擬器(或兩者方式同時使用),以編程方式依次連接到每個Android設備,然后運行一個或多個測試。還可以以編程方式啟動模擬器配置,運行一個或多個測試,然后關閉模擬器。(monkeyrunner API可以跨多個設備,一次啟動全部模擬器來實施測試套件)
②功能測試:monkeyrunner可以對Android應用程序進行自動化的從頭到尾的測試。可以通過擊鍵或觸摸事件提供輸入值,並將結果視為屏幕截圖。(為Android應用自動執行一次功能測試,然后觀察輸出結果的截屏)
③回歸測試:monkeyrunner可以通過運行應用程序並將其輸出屏幕截圖與一組已知已存在正確的屏幕截圖進行比較來測試應用程序的穩定性。
④可擴展的自動化:由於monkeyrunner是一個API工具包(在python中可以理解為可調用的一個模塊,模塊中是工具類),可以開發一個基於Python的模塊和程序的整個系統來控制Android設備。除了使用monkeyrunner API本身,您還可以使用標准的Python os和 subprocess 模塊來調用Android工具,例如 Android Debug Bridge。
⑤還可以自己封裝操作Android設備/Android模擬器的工具類添加到monkeyrunner API中,即使用插件擴展monkeyrunner
Monkeyrunner與Monkey的區別
1、monkeyrunner和money沒有什么直接的關系;monkey是在Android設備/Android模擬器直接運行adb shell命令生成隨機事件來進行測試的。相比較而言,monkeyrunner則是通過API發送特定的命令和事件來控制設備。(類比selenium工具)
2、為了支持黑盒自動化測試的場景,Android SDK提供了monkey和monkeyrunner兩個測試工具,這兩個測試工具除了名字類似外,還都可以向待測應用發送按鍵等消息,往往容易產生混淆,以下是他倆的不同之處。
Monkey測試工具:
①monkey運行在設備或者模擬器中,可以脫離PC運行,其運行時如下圖所示:
Monkeyrunner測試工具:
①Monkeyrunner測試工具是在工作站上通過API定義的特定命令和事件控制設備或模擬器。
②monkeyrunner運行在PC上,需要通過客戶端/服務端的的模式向Android設備或者Android模擬器上的Android應用發送指令來執行測試,其運行時如下圖所示:
3、普遍的做法是將monkey作為一個向待測Android應用發送隨機按鍵消息的測試工具,驗證待測Android應用在這些隨機性的輸入事件中面前是否會有閃退或者崩潰。
而monkeyrunner則接受一個明確的測試腳本(使用python語言編寫的)來實現對Android應用的控制。
4、雖然monkey也可以根據一個指定的命令腳本發送按鍵消息,但其不支持條件判斷,也不支持讀取界面的信息來執行驗證操作。(monkey測試工具只是用於測試Android應用的穩定性,通過查看money命令的運行日志校驗隨機事件運行期間是否Android應用發生異常)
而monkeyrunner的測試腳本中有明確的條件判斷等語句,可用來做功能測試。
總結:
①實際操作中,monkey由於缺少必要的條件判斷等命令,難以在功能測試上有所作為,只能作為生成一些隨機事件的工具,測試Android應用程序的健壯程度,待測Android應用崩潰后可以根據monkey產生的日志,再用monkey命令創建一個重現步驟,供開發調試。monkey服務器模式更適合用於黑盒測試,不建議用於自動化測試。
②Monkeyrunner雖然有Python和Java類庫的強大支持,但其自身提供的API有限,還得需要插件擴展其功能。
monkeyrunner API
MonkeyRunner工具(monkeyrunner API)( com.android.monkeyrunner包中)主要有三個類: MonkeyRunner 、 MonkeyDevice 、 MonkeyImage
① MonkeyRunner 類:提供連接Andriod真機和Andriod模擬器方法 waitForConnection(float timeout,string deviceid) ,還有顯示提示顯示信息的 alert() 方法。
② MonkeyDevice 類:表示設備或模擬器。提供了安裝和卸載程序包、開啟Activity、發送按鍵和點擊事件、運行測試包等方法。
拖拉控件:drag(tuple start,tuple end,float duration,integer steps) # duration手勢持續時間
按鍵: press(string keycode,dictionary type) # keycode:KEYCODE_HOME,..;type:DOWN ,UP,DOWN_AND_UP...
安裝應用: installPackage(pc端存放apk的路徑)
啟動應用: starActivity(package+'/'+activity) # '/'用來連接包名和界面名(一個參數)
點擊: touch(integer x,integer y, integer type) # type:DOWN,UP,DOWN_AND_UP...
輸入: type(string message)
截屏: takeSnapshot()
③ MonkeyImage 類:此類提供捕獲屏幕,將位圖圖像轉換為各種格式,比較兩個MonkeyImage對象以及將圖像寫入文件的方法。
圖像對比 :sameAs(MonkeyImage other,float percent) # 對比的相似度,結果boolean類型
圖像保存 :writetoFile(string path,string format)
在Python程序中,可以將每個類作為Python模塊進行訪問。monkeyrunner測試工具不會自動導入這些模塊。要導入模塊,請使用Python from 語句:
from com.android.monkeyrunner import <module>
運行monkeyrunner
可以從文件中直接運行monkeyrunner程序;也可以在交互式會話(即cmd終端)中輸入monkeyrunner語句。
①如果提供文件名作為參數,則該monkeyrunner命令將文件的內容作為Python程序運行; (使用Python編寫測試代碼文件,在CMD中執行 monkeyrunner 文件名.py運行)
monkeyrunner -plugin <plugin_jar> <program_filename> <program_options>
參數詳解:
參數 | 描述 |
---|---|
-plugin <plugin_jar> |
(可選)指定.jar 包含monkeyrunner插件的文件。要了解有關monkeyrunner插件的更多信息,請參閱 使用插件擴展monkeyrunner。要指定多個文件,請多次包含該參數。 |
<program_filename> |
如果提供此參數,則該monkeyrunner 命令將該文件的內容作為Python程序運行。如果未提供參數,則該命令將啟動交互式會話。 |
<program_options> |
(可選)<program_file>中程序的標志和參數。 |
②如果不提供文件名作為monkeyrunner命令的參數,則會啟動一個交互式會話。(在CMD命令窗口直接運行monkeyrunner)如下圖:
【注意】在運行monkeyrunner命令之前必須先運行相應的Android模擬器或連接Android真機,否則monkeyrunner工具無法連接到設備。
monnkeyrunner測試工具使用實例
實例1:卸載舊的Android APP,安裝新的Android APP
方式一:
①連接Android模擬器成功。
②打開CMD窗口,運行monkeyrunner命令。
③進入monkeyrunner的shell命令交互模式后,逐條輸入以下命令
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage device = MonkeyRunner.waitForConnection() device.removePackage('com.baidu.searchbox') device.installPackage(r'E:\Android_apk\baidusearch1006979t.apk')
(1)輸入命令前的夜神模擬器:
(2)輸入第三行命令后的夜神模擬器:
(3)輸入第四行命令后的夜神模擬器:
(4)CMD終端命令行截圖:
方式二:
①編寫Python測試代碼:
# coding=utf-8 # 引入本程序所用到的模塊 from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage # 連接手機設備 device = MonkeyRunner.waitForConnection() # 截圖 result = device.takeSnapshot() # 將截圖保存到文件 result.writeToFile('E:\\manage\\Test1_001.png', 'png') # 卸載APP device.removePackage('com.baidu.searchbox') print('Uninstall Success!') # 暫停5秒 MonkeyRunner.sleep(5) # 截圖 result = device.takeSnapshot() result.writeToFile('E:\\manage\\Test1_002.png', 'png') # 安裝新的APP device.installPackage(r'E:\Android_apk\baidusearch1006979t.apk') print('Install Success!') # 暫停5秒 MonkeyRunner.sleep(5) # 截圖 result = device.takeSnapshot() # 將截圖保存到文件 result.writeToFile('E:\\manage\\Test1_003.png', 'png')
【注意】monkeyrunner命令運行python程序時需要去除中文注釋;或者在模塊開頭添加#coding=utf-8。
②將上述python腳本保存為test_1.py,保存路徑為E:\python_script\test_1.py。
③CMD終端中執行test_1.py腳本:
monkeyrunner E:\python_script\test_1.py
運行截圖:
③檢查Android模擬器里的百度app是否更新
④檢查保存Android模擬器截屏的文件夾E:\\manage。檢查是否和程序中的截屏信息相同。
monkeyrunner測試工具常用的知識點
①引入程序所用的模塊
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage
或者,使用別名的方式引入程序所用的模塊
from com.android.monkeyrunner import MonkeyRunner as mr from com.android.monkeyrunner import MonkeyDevice as md from com.android.monkeyrunner import MonkeyImage as mi #如果給導入的模塊起了別名,就必須使用別名,否則會出現錯誤。 #比如連接設備或模擬器,起了以上別名后,命令應該如下: device=mr.waitForConnection()
②#連接到Android設備或Android模擬器
#參數1:超時時間,單位秒,浮點數。默認是無限期地等待。 #參數2:串deviceid,指定的設備名稱。默認為當前設備(手機優先,比如手機通過USB線連接到PC、其次為模擬器)。
#默認連接: device = MonkeyRunner.waitForConnection() #參數連接: device = MonkeyRunner.waitForConnection(1.0,'4df74b8XXXXXXX')
③向Android設備或Android模擬器安裝APK
#以下兩種方式都是對的 #參數可以為絕對路徑,也可為相對路徑
#安裝成功返回true
device.installPackage('E:/JAVA/monkeyrunner/Test1/ThinkDrive_new.apk') device.installPackage('E:\\JAVA\\monkeyrunner\\Test1\\ThinkDrive_new.apk')
④卸載Android設備或Android模擬器中的APK
#參數為APK包名 device.removePackage('cn.richinfo.thinkdrive')
⑤啟動任意的Activity(Android應用的啟動)
#device.startActivity(component="包名/啟動Activity") #以下兩種都可以 device.startActivity(component="cn.richinfo.thinkdrive/cn.richinfo.thinkdrive.ui.activities.NavigateActivity") device.startActivity(component="cn.richinfo.thinkdrive/.ui.activities.NavigateActivity")
⑥手機截圖+截圖保存至本機
#獲取設備的屏蔽緩沖區,產生了整個顯示器的屏蔽捕獲。(截圖) result=device.takeSnapshot() #返回一個MonkeyImage對象(點陣圖包裝),可以用以下命令將圖保存到文件 result.writeToFile('E:\\JAVA\\monkeyrunner\\Test1\\Test1_001.png','png')
⑦等待(類比python程序中的sleep)
#暫停目前正在運行的程序指定的秒數 #MonkeyRunner.sleep(秒數,浮點數) MonkeyRunner.sleep(5)
⑧字符串發送到鍵盤
#device.type('字符串') device.type('hongge')
⑨喚醒Android設備的屏幕
#鎖屏后,屏幕關閉,可以用下命令喚醒 device.wake()
⑩重啟手機
device.reboot()
①①模擬Android滑動
#device.drag(X,Y,D,S) #X 開始坐標 #Y 結束坐標 #D 拖動持續時間(以秒為單位),默認1.0秒 #S 插值點時要采取的步驟。默認值是10 device.drag((100,1053),(520,1053),0.1,10)
①②在指定位置發送觸摸事件+發送指定類型指定鍵碼的事件
#device.touch(x,y,觸摸事件類型---點擊屏幕) #x,y的單位為像素 device.touch(520,520, 'DOWN_AND_UPshishi)
①③按鍵操作
#device.press(參數1:鍵碼, 參數2:觸摸事件類型) #參數1:見android.view.KeyEvent #參數2,如有TouchPressType()返回的類型-觸摸事件類型,有三種。 #觸摸事件類型: #1、DOWN 發送一個DOWN事件。指定DOWN事件類型發送到設備,對應的按一個鍵或觸摸屏幕上。 #2、UP 發送一個UP事件。指定UP事件類型發送到設備,對應釋放一個鍵或從屏幕上抬起。 #3、DOWN_AND_UP 發送一個DOWN事件,然后一個UP事件。對應於輸入鍵或點擊屏幕。
#以上三種事件做為press()參數或touch()參數 #按下HOME鍵 device.press('KEYCODE_HOME', MonkeyDevice.DOWN_AND_UP) #按下BACK鍵 device.press('KEYCODE_BACK', MonkeyDevice.DOWN_AND_UP) #按下下導航鍵 device.press('KEYCODE_DPAD_DOWN', MonkeyDevice.DOWN_AND_UP) #按下上導航鍵 device.press('KEYCODE_DPAD_UP', MonkeyDevice.DOWN_AND_UP) #按下OK鍵 device.press('KEYCODE_DPAD_CENTER', MonkeyDevice.DOWN_AND_UP)
Android設備或虛擬機中相應的按鍵對應的名稱如下:
home鍵: KEYCODE_HOME
back鍵: KEYCODE_BACK
send鍵: KEYCODE_CALL
end鍵: KEYCODE_ENDCALL
上導航鍵: KEYCODE_DPAD_UP
下導航鍵: KEYCODE_DPAD_DOWN
左導航: KEYCODE_DPAD_LEFT
右導航鍵: KEYCODE_DPAD_RIGHT
ok鍵: KEYCODE_DPAD_CENTER
上音量鍵: KEYCODE_VOLUME_UP
下音量鍵: KEYCODE_VOLUME_DOWN
power鍵: KEYCODE_POWER
camera鍵: KEYCODE_CAMERA
menu鍵: KEYCODE_MENU