Appium+python自動化(二十三)- 真假美猴王Monkeyrunner與Monkey傻傻的分不清楚(超詳解)
簡介
看《西遊記》第五十七回,說是“六耳獼猴”化作孫悟空的摸樣,傷了唐僧,後又和孫悟空大打出手…… 這位假孫悟空,實力不用多說了吧,和真孫悟空一般無二,大戰孫悟空,鬧到上天入地下海。 在唐僧那:念緊箍咒,兩個都喊疼,自然看不出哪個真假; 到天宮:拖塔天王拿照妖鏡照,也看不出; 又到觀音那:觀音也看不出。最後到幽冥處閻羅那,經“諦聽”聽過之後,“諦聽”卻說:“我看出來了,卻不敢說” 最後還是如來老佛爺道出六耳真身並用金鉢盂罩住,才被孫悟空一棍子打死。想必各位小夥伴都看過這以精彩片段。不過據知情人士說真假美猴王存在陰謀,這裡有黑幕:說是真的孫悟空被打死了,活下來的是假的。好了廢話少說,還是回到今天的主題:真假美猴王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解釋了標誌和引數。
引數 | 描述 |
---|---|
-plugin <plugin_jar> |
(可選)指定.jar 包含monkeyrunner外掛的檔案。要了解有關monkeyrunner外掛的更多資訊,請參閱 使用外掛擴充套件monkeyrunner。要指定多個檔案,請多次包含該引數。 |
<program_filename> |
如果提供此引數,則該monkeyrunner 命令將該檔案的內容作為Python程式執行。如果未提供引數,則該命令將啟動互動式會話。 |
<program_options> |
(可選)<program_file>中程式的標誌和引數。 |
執行monkeyrunner
命令語法為:
monkeyrunner -plugin <plugin_jar> <program_filename> <program_options>
方式一:在CMD命令視窗直接執行monkeyrunner
方式二:使用Python編寫測試程式碼檔案,在CMD中執行monkeyrunner hongge.py執行
不論使用哪種方式,您都需要呼叫SDK目錄的tools子目錄下的monkeyrunner命令。
注意:在執行monkeyrunner之前必須先執行相應的模擬器或連線真機,否則monkeyrunner無法連線到裝置 執行模擬器有兩種方法:1、通過eclipse中執行模擬器 2、在CMD中通過命令呼叫模擬器 這裡介紹通過命令,在CMD中執行模擬器的方法 emulator -avd test 上面命令中test是指模擬器的名稱。
附:這部分前邊已經講解過,在這裡就不再贅述)
問題: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命令互動模式後,逐條輸入以下命令
1 from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage2 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')
#啟動任意的Activity
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.好了時間也不早了,今天就囉嗦、水到這裡吧,哈哈!晚安。好夢!!!
您的肯定就是我進步的動力。如果你感覺還不錯,就請鼓勵一下吧!記得點波 推薦 哦!!!(點選右邊的小球即可)
個人公眾號
微信群
&n