簡介
看《西游記》第五十七回,說是“六耳獼猴”化作孫悟空的摸樣,傷了唐僧,后又和孫悟空大打出手…… 這位假孫悟空,實力不用多說了吧,和真孫悟空一般無二,大戰孫悟空,鬧到上天入地下海。 在唐僧那:念緊箍咒,兩個都喊疼,自然看不出哪個真假; 到天宮:拖塔天王拿照妖鏡照,也看不出; 又到觀音那:觀音也看不出。最后到幽冥處閻羅那,經“諦聽”聽過之后,“諦聽”卻說:“我看出來了,卻不敢說” 最后還是如來老佛爺道出六耳真身並用金缽盂罩住,才被孫悟空一棍子打死。想必各位小伙伴都看過這以精彩片段。不過據知情人士說真假美猴王存在陰謀,這里有黑幕:說是真的孫悟空被打死了,活下來的是假的。好了廢話少說,還是回到今天的主題:真假美猴王Monkeyrunner與Monkey傻傻的分不清楚。
今天宏哥就帶着各位小伙伴和童鞋們再當一回和尚:如來佛祖辨一辨真假美猴王,前邊我們已經對monkey做過一些詳細的介紹和講解,今天我們就再來介紹和講解一下monkeyrunner。看看他們之間的到底是一樣還是有區別的。
monkeyrunner簡介
1.monkeyrunner工具使用Jython,這是一種使用Java編程語言的Python實現。Jython允許monkeyrunner API與Android框架輕松交互。使用Jython,您可以使用Python語法來訪問API的常量,類和方法。MonkeyRunner工具是使用Jython(使用Java編程語言實現的
Python)寫出來的,它提供了多個API,通過monkeyrunner API 可以寫一個Python的程序來模擬操作控制Android設備app,測試其穩定性並通過截屏可以方便地記錄出現的問題。
2.我們來看一下monkeyrunner官網是如何介紹monkeyrunner的:
官網介紹(已翻譯成中文)宏哥在這里給小伙伴截取一段翻譯,如下:
monkeyrunner工具提供了一個API,用於編寫從Android代碼外部控制Android設備或模擬器的程序。使用monkeyrunner,您可以編寫一個Python程序,安裝Android應用程序或測試包,運行它,向其發送擊鍵,截取其用戶界面,並在工作站上存儲屏幕截圖、
monkeyrunner工具主要用於測試功能/框架級別的應用程序和設備以及運行單元測試套件,但您可以將其用於其他目的。
monkeyrunner工具與UI / Application Exerciser Monkey無關 ,也稱為monkey工具。該monkey工具adb直接在設備或仿真器上的shell中運行, 並生成用戶和系統事件的偽隨機流。相比之下,monkeyrunner工具通過從API發送特定命令和事件來控制工作站中的設備和
仿真器。
3.monkeyrunner即android SDK中自帶的工具之一,此工具提供API可按制android設備或模擬器。
4.有興趣的小伙伴們或者童鞋可以查看一下monkeyrunner官網:https://www.android-doc.com/tools/help/monkeyrunner_concepts.html
5.monkeyrunner 路徑:Andriod_SDK\tools
MonkeyRunner工具獨特功能
1.多設備控制:monkeyrunner API可以跨多個設備或仿真器應用一個或多個測試套件。您可以物理連接所有設備或立即啟動所有模擬器(或兩者),以編程方式依次連接到每個設備,然后運行一個或多個測試。您還可以以編程方式啟動模擬器配置,運行一個或多個測試,然后關閉模擬器。
2.功能測試:monkeyrunner可以對Android應用程序進行自動化的從頭到尾的測試。您可以通過擊鍵或觸摸事件提供輸入值,並將結果視為屏幕截圖。
3.回歸測試 - monkeyrunner可以通過運行應用程序並將其輸出屏幕截圖與一組已知正確的屏幕截圖進行比較來測試應用程序的穩定性。
4.可擴展的自動化 - 由於monkeyrunner是一個API工具包,您可以開發一個基於Python的模塊和程序的整個系統來控制Android設備。除了使用monkeyrunner API本身,您還可以使用標准的Python os
和 subprocess
模塊來調用Android工具,例如 Android Debug Bridge。
您還可以將自己的類添加到monkeyrunner API中。這在“ 使用插件擴展monkeyrunner ”一節中有更詳細的描述 。
Monkeyrunner與Monkey區別
monkeyrunner和money沒有什么直接的關系,monkey是在設備直接運行adb shell命令生成隨機事件來進行測試的。相比較而言,monkeyrunner則是通過API發送特定的命令和事件來控制設備。
為了支持黑盒自動化測試的場景,Android SDK提供了monkey和monkeyrunner兩個測試工具,這兩個測試工具除了名字類似外,還都可以向待測應用發送按鍵等消息,往往容易產生混淆,以下是他倆的不同之處。
Monkey:
Monkey工具直接運行在設備或模擬器的adb shell中,生成用戶或系統的偽隨機事件流。
1.monkey運行在設備或者模擬器上邊,可以脫離PC運行,其運行時如下圖所示。
Monkeyrunner:
Monkeyrunner工具是在工作站上通過API定義的特定命令和事件控制設備或模擬器。
而monkeyrunner運行在PC上,需要通過服務器/客戶端的的模式向設備或者模擬器上的android應用發送指令來執行測試,其運行時如下圖所示。
2.普遍的做法是將monkey作為一個向待測應用發送隨機按鍵消息的測試工具,驗證待測應用在這些隨機性的輸入面前是否會有閃退或者崩潰。而monkeyrunner則接受一個明確的測試腳本(使用python語言編寫的)。
3.雖然monkey也可以根據一個指定的命令腳本發送按鍵消息,但其不支持條件判斷,也不支持讀取界面的信息來執行驗證操作。而monkeyrunner的測試腳本中有明確 的條件判斷等語句,可用來做功能測試。
總結:
實際操作中,monkey由於缺少必要的條件判斷等命令,難以在功能測試上有所作為,只能作為生成一些隨機事件的工具,測試應用程序的健壯程度,待測應用崩潰后可以根據monkey打印的日志,再用monkey創建一個重現步驟,供開發調試。monkey服務器模式更適合用於黑盒測試,不建議用於自動化測試。
而Monkeyrunner雖然有Python和Java類庫的強大支持,但其自身提供的API有限,還得需要插件擴展其功能。
monkeyrunner API
monkeyrunner API包含在包中的三個模塊中 com.android.monkeyrunner
:
1.MonkeyRunner
:monkeyrunner程序的一類實用方法。此類提供了將monkeyrunner連接到設備或模擬器的方法。它還提供了為monkeyrunner程序創建UI以及顯示內置幫助的方法。
2.MonkeyDevice
:表示設備或模擬器。此類提供了安裝和卸載軟件包,啟動Activity以及向應用程序發送鍵盤或觸摸事件的方法。您還可以使用此類來運行測試包。
3.MonkeyImage
:表示屏幕捕獲圖像。此類提供捕獲屏幕,將位圖圖像轉換為各種格式,比較兩個MonkeyImage對象以及將圖像寫入文件的方法。
在Python程序中,您可以將每個類作為Python模塊進行訪問。monkeyrunner工具不會自動導入這些模塊。要導入模塊,請使用Python from
語句:
1 from com.android.monkeyrunner import <module>
<module>
您要導入的類名 在哪里。from
通過用逗號分隔模塊名稱,可以在同一語句中導入多個模塊。
運行monkeyrunner
您可以從文件中運行monkeyrunner程序,也可以在交互式會話中輸入monkeyrunner語句。您可以通過調用SDK目錄子目錄中的monkeyrunner
命令來執行這兩項操作tools/
。如果提供文件名作為參數,則該monkeyrunner
命令將文件的內容作為Python程序運行; 否則,它會啟動一個交互式會話。
該monkeyrunner
命令的語法是
1 monkeyrunner -plugin <plugin_jar> <program_filename> <program_options>
表1解釋了標志和參數。
表1. monkeyrunner
標志和參數。
參數 | 描述 |
---|---|
-plugin <plugin_jar> |
(可選)指定.jar 包含monkeyrunner插件的文件。要了解有關monkeyrunner插件的更多信息,請參閱 使用插件擴展monkeyrunner。要指定多個文件,請多次包含該參數。 |
<program_filename> |
如果提供此參數,則該monkeyrunner 命令將該文件的內容作為Python程序運行。如果未提供參數,則該命令將啟動交互式會話。 |
<program_options> |
(可選)<program_file>中程序的標志和參數。 |
運行monkeyrunner
命令語法為:
方式一:在CMD命令窗口直接運行monkeyrunner
方式二:使用Python編寫測試代碼文件,在CMD中執行monkeyrunner hongge.py運行
不論使用哪種方式,您都需要調用SDK目錄的tools子目錄下的monkeyrunner命令。
附:這部分前邊已經講解過,在這里就不再贅述)
問題:CMD運行提示monkeyrunner不是內部或外部命令,也不是可運行的程序或批處理文件。
解決:電腦環境變量未配置,將monkeyrunner所在目錄配在環境變量里。
變量名:Path
變量值:D:\android\android-sdk-windows\tools;D:\android\android-sdk-windows\platform-tools
實例
實例一:卸載舊的APP,安裝新的APP
*准備
a. 連接安卓夜神模擬器設備
b. 運行CMD,檢測是否連接成功
CMD>adb devices
附:(這部分前邊已經講解過,在這里就不再贅述)
問題:CMD運行提示adb不是內部或外部命令,也不是可運行的程序或批處理文件。
解決:電腦環境變量未配置,將adb所在目錄配在環境變量里。
*方式一:
1.打開CMD,運行monkeyrunner
2.進入monkeyrunner的shell命令交互模式后,逐條輸入以下命令
2 device = MonkeyRunner.waitForConnection()
3 device.removePackage('com.taobao.taobao')
4 device.installPackage('C:\\Users\\DELL\\Desktop\\702757.apk')
(1)輸入命令前的夜神模擬器:
(2)輸入第三行命令后的夜神模擬器
(3)輸入第四行的夜神模擬器
注:每條命令的作用,請見方法二中的注解
實操如圖:
c.檢查手機app是否已更新
*方式二:
a. 編寫Python測試代碼
1 # File: Test1.py 2 # Vision: V1.0 3 # Author: hongge QQ群:707699217 4 # 引入本程序所用到的模塊 5 from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage 6 7 # 連接手機設備 8 device = MonkeyRunner.waitForConnection() 9 10 # 截圖 11 result = device.takeSnapshot() 12 # 將截圖保存到文件 13 result.writeToFile('E:\\JAVA\\monkeyrunner\\Test1\\Test1_001.png','png') 14 15 # 卸載APP 16 device.removePackage('cn.richinfo.thinkdrive') 17 print ('Uninstall Success!') 18 19 # 暫停5秒 20 MonkeyRunner.sleep(5) 21 22 # 截圖 23 result = device.takeSnapshot() 24 result.writeToFile('E:\\JAVA\\monkeyrunner\\Test1\\Test1_002.png','png') 25 26 # 安裝新的APP 27 device.installPackage('E:\\JAVA\\monkeyrunner\\Test1\\ThinkDrive_new.apk') 28 print ('Install Success!') 29 30 # 截圖 31 result = device.takeSnapshot() 32 result.writeToFile('E:\\JAVA\\monkeyrunner\\Test1\\Test1_003.png','png')
注:拷貝運行時請去掉中文注釋;或者在開頭加入 #coding=utf-8
b.執行Test1.py腳本
Monkeyrunner C:\Users\DELL\Desktop\test.py
實操如圖:
c.檢查手機app是否已更新
d.查看截圖文件夾,截圖和上邊逐條輸入命令,宏哥截得模擬器一模一樣的。
e.注意如果截圖不一樣自己加個等待時間,就會一樣,參考代碼:
1 #coding=utf-8 2 # File: Test1.py 3 4 # Vision: V1.0 5 6 # Author: hongge QQ群:707699217 7 8 # 引入本程序所用到的模塊 9 10 from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage 11 12 13 14 # 連接手機設備 15 16 device = MonkeyRunner.waitForConnection() 17 18 19 20 # 截圖 21 22 result = device.takeSnapshot() 23 24 # 將截圖保存到文件 25 26 result.writeToFile('C:\\Users\\DELL\\Desktop\\test\\Test1_001.png','png') 27 28 29 30 # 卸載APP 31 32 device.removePackage('com.taobao.taobao') 33 34 print ('Uninstall Success!') 35 36 37 38 # 暫停5秒 39 40 MonkeyRunner.sleep(5) 41 42 43 44 # 截圖 45 46 result = device.takeSnapshot() 47 48 result.writeToFile('C:\\Users\\DELL\\Desktop\\test\\Test1_002.png','png') 49 50 51 # 暫停5秒 52 53 MonkeyRunner.sleep(5) 54 55 56 # 安裝新的APP 57 58 device.installPackage('C:\\Users\\DELL\\Desktop\\702757.apk') 59 60 print ('Install Success!') 61 62 # 暫停5秒 63 64 MonkeyRunner.sleep(5) 65 66 # 截圖 67 68 result = device.takeSnapshot() 69 70 result.writeToFile('C:\\Users\\DELL\\Desktop\\test\\Test1_003.png','png')
monkeyrunner內置幫助
您可以通過運行以下命令為monkeyrunner生成API參考:
1 monkeyrunner help.py <format> <outfile>
論點是:
<format>
或者是text
純文本的輸出或html
用於HTML輸出。<outfile>
是輸出文件的路徑限定名稱。
使用插件擴展monkeyrunner
您可以使用Java編程語言編寫的類擴展monkeyrunner API,並將其構建為一個或多個.jar
文件。您可以使用此功能使用您自己的類擴展monkeyrunner API或擴展現有類。您還可以使用此功能初始化monkeyrunner環境。
要為monkeyrunner提供插件,請monkeyrunner
使用表1中-plugin <plugin_jar>
描述的參數 調用該命令 。
在你的插件代碼,你可以導入和擴展的主要monkeyrunner類 MonkeyDevice
,MonkeyImage
和MonkeyRunner
在com.android.monkeyrunner
(見的monkeyrunner API)。
請注意,插件不允許您訪問Android SDK。您無法導入包等com.android.app
。這是因為monkeyrunner與框架API級別下的設備或模擬器交互。
插件啟動類
.jar
插件 的文件可以指定在腳本處理開始之前實例化的類。要指定此類,請將密鑰添加 MonkeyRunnerStartupRunner
到.jar
文件的清單中。該值應該是啟動時要運行的類的名稱。以下代碼段顯示了如何在ant
構建腳本中執行此操作:
1 <jar jarfile="myplugin" basedir="${build.dir}"> 2 <manifest> 3 <attribute name="MonkeyRunnerStartupRunner" value="com.myapp.myplugin"/> 4 </manifest> 5 </jar>
要訪問monkeyrunner的運行時環境,啟動類可以實現 com.google.common.base.Predicate<PythonInterpreter>
。例如,此類在默認命名空間中設置一些變量:
1 package com.android.example; 2 3 import com.google.common.base.Predicate; 4 import org.python.util.PythonInterpreter; 5 6 public class Main implements Predicate<PythonInterpreter> { 7 @Override 8 public boolean apply(PythonInterpreter anInterpreter) { 9 10 /* 11 * Examples of creating and initializing variables in the monkeyrunner environment's 12 * namespace. During execution, the monkeyrunner program can refer to the variables "newtest" 13 * and "use_emulator" 14 * 15 */ 16 anInterpreter.set("newtest", "enabled"); 17 anInterpreter.set("use_emulator", 1); 18 19 return true; 20 }
monkeyrunner環境搭建
1.安裝並配置好jdk環境
2.安裝android sdk
3.安裝python
4.monkeyrunner環境變量配置: {Path}\Andriod_SDK\tools
安裝結果檢測
在docs命令控制台輸入命令:monkeyrunner出現如下顯示內容則說明安裝成功
Tips:退出monkeyrunner命令行模式可以 使用快捷鍵 ctrl+D退出。
小結
1.在方式二運行monkeyrunner報錯(190724 14:33:20.837:S [main] [com.android.monkeyrunner.MonkeyRunnerOptions] Script terminated due to an exception)
解決方法,報出該錯誤是使用的notepad++編碼格式問題,notepad++默認編碼格式是ansi,我們使用的monkeyrunner腳本格式是utf-8,因此有沖突
修改方法如下
首先,看我們的腳本編碼格式是什么,我這里的是utf-8,因此不用再做修改
3.如果編碼格式不是utf-8的,就要對它進行修改了,點擊格式,選擇utf-8,再保存,也可選擇無BOM格式的
4.再來運行一下,這次成功了
2.monkeyrunner常用的知識點
1 from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage
#引入程序所用的模塊,使用別名
1 from com.android.monkeyrunner import MonkeyRunner as mr 2 from com.android.monkeyrunner import MonkeyDevice as md 3 from com.android.monkeyrunner import MonkeyImage as mi 4 #如果給導入的模塊起了別名,就必須使用別名,否則會出現錯誤。 5 #比如連接設備或模擬器,起了以上別名后,命令應該如下: 6 device=mr.waitForConnection()
#連接到設備或模擬器
1 #參數1:超時時間,單位秒,浮點數。默認是無限期地等待。 2 #參數2:串deviceid,指定的設備名稱。默認為當前設備(手機優先,比如手機通過USB線連接到PC、其次為模擬器)。 3 #默認連接: 4 device = MonkeyRunner.waitForConnection() 5 #參數連接: 6 device = MonkeyRunner.waitForConnection(1.0,'4df74b8XXXXXXX')
#向設備或模擬器安裝APK
1 #以下兩種方式都是對的 2 device.installPackage('E:/JAVA/monkeyrunner/Test1/ThinkDrive_new.apk') 3 device.installPackage('E:\\JAVA\\monkeyrunner\\Test1\\ThinkDrive_new.apk') 4 #參數可以為絕對路徑,也可為相對路徑
#卸載設備或模擬器中的APK
1 #參數為APK包名 2 device.removePackage('cn.richinfo.thinkdrive')
1 #device.startActivity(component="包名/啟動Activity") 2 #以下兩種都OK 3 device.startActivity(component="cn.richinfo.thinkdrive/cn.richinfo.thinkdrive.ui.activities.NavigateActivity") 4 device.startActivity(component="cn.richinfo.thinkdrive/.ui.activities.NavigateActivity")
#手機截圖
1 #獲取設備的屏蔽緩沖區,產生了整個顯示器的屏蔽捕獲。(截圖) 2 result=device.takeSnapshot() 3 #返回一個MonkeyImage對象(點陣圖包裝),我們可以用以下命令將圖保存到文件 4 result.writeToFile('E:\\JAVA\\monkeyrunner\\Test1\\Test1_001.png','png')
#暫停
1 #暫停目前正在運行的程序指定的秒數 2 #MonkeyRunner.sleep(秒數,浮點數) 3 MonkeyRunner.sleep(5)
1 #device.type('字符串') 2 device.type('hongge')
1 #鎖屏后,屏幕關閉,可以用下命令喚醒 2 device.wake()
#重起手機
1 device.reboot()
#模擬滑動
1 #device.drag(X,Y,D,S) 2 #X 開始坐標 3 #Y 結束坐標 4 #D 拖動持續時間(以秒為單位),默認1.0秒 5 #S 插值點時要采取的步驟。默認值是10 6 device.drag((100,1053),(520,1053),0.1,10)
#在指定位置發送觸摸事件
1 #device.touch(x,y,觸摸事件類型) 2 #x,y的單位為像素 3 #觸摸事件類型,請見下文中Findyou對device.press描述 4 5 device.touch(520,520,'DOWN_AND_UP')
#發送指定類型指定鍵碼的事件
1 #device.press(參數1:鍵碼,參數2:觸摸事件類型) 2 #參數1:見android.view.KeyEvent 3 #參數2,如有TouchPressType()返回的類型-觸摸事件類型,有三種。 4 #1、DOWN 發送一個DOWN事件。指定DOWN事件類型發送到設備,對應的按一個鍵或觸摸屏幕上。 5 #2、UP 發送一個UP事件。指定UP事件類型發送到設備,對應釋放一個鍵或從屏幕上抬起。 6 #3、DOWN_AND_UP 發送一個DOWN事件,然后一個UP事件。對應於輸入鍵或點擊屏幕。 7 以上三種事件做為press()參數或touch()參數 8 9 #按下HOME鍵 10 device.press('KEYCODE_HOME',MonkeyDevice.DOWN_AND_UP) 11 #按下BACK鍵 12 device.press('KEYCODE_BACK',MonkeyDevice.DOWN_AND_UP) 13 #按下下導航鍵 14 device.press('KEYCODE_DPAD_DOWN',MonkeyDevice.DOWN_AND_UP) 15 #按下上導航鍵 16 device.press('KEYCODE_DPAD_UP',MonkeyDevice.DOWN_AND_UP) 17 #按下OK鍵 18 device.press('KEYCODE_DPAD_CENTER',MonkeyDevice.DOWN_AND_UP)
3.好了時間也不早了,今天就啰嗦、水到這里吧,哈哈!晚安。好夢!!!
您的肯定就是我進步的動力。如果你感覺還不錯,就請鼓勵一下吧!記得點波 推薦 哦!!!(點擊右邊的小球即可)
個人公眾號
微信群