Monkey自己就能寫腳本,你不試試嗎?
一、前言
之前有講解過 Android 下 Monkey 的腳本命令,而且還用 Python 寫了一個非常簡單的利用 Monkey 的測試腳本。
雖然之前是利用 Python + Monkey + adb 命令,完成的一連串自動化測試的腳本。而 Monkey 本身也是支持編寫腳本的,這個腳本叫 MonkeyScript(下文簡稱MS),只是 Google 官方,并沒有相關的文檔進行描述。可我們依然可以從源碼中找到蛛絲馬跡。
本片文章適用于程序員和測試人員,會從源碼的角度來分析 Monkey Script,如果僅僅是測試人員,對此不感興趣,可以跳過相關小結進行閱讀。希望閱讀者有一點 ADB 和 Monkey 腳本的經驗,這樣更方便閱讀。
二、什么是MonkeyScript
MS 是官方提供的,除了直接使用 Monkey 命令,像猴子一樣隨機亂點之外,還可以通過編寫腳本的形式,完成一系列固定的操作。MS 提供一整套完善的 API 來進行支持,主要還是基于坐標點的操作,包含常用的:點擊、長按、輸入、等待等操作。
1、MonkeyScript的使用
MS 雖然需要編寫測試腳本,但是它還是屬于 Monkey 命令的一部分,需要通過 Monkey 命令進行啟動、運行。
Monkey 啟動 MonkeyScript 的命令如下:
- adb shell monkey -f <MonkeyScript> <EventCount>
通過 -f 參數即可指定一個 MS 腳本進行執行。需要注意的是,因為 adb shell 的運行環境是在待測試的 Android 設備上,所以需要將 MS 腳本 ,使用 adb pull 命令,傳到待測試的設備上,然后再進行運行。
2、MonkeyScript的常用API
MS 其實提供了非常完備的 API ,但是本篇文章并不想只是一個幫助文檔,這里僅介紹一些常用的 API ,想查看完整的 API ,可以選擇閱讀 MS 相關的源碼,或者可以在本公眾號,回復關鍵字『MonkeyScriptAPI』即可得到完整的 API 文檔。
1、點擊事件(DispatchPointer)
DispatchPointer 命令用于向一個指定的坐標位置,發送單個手勢消息,一般用它來模擬點擊的操作。
它完整的方法簽名是:
DispatchPointer ( downTime , eventTime , action , x , y , pressure , size , metaState , xPrecision , yPrecision , device , edgeFlags)
其實這么多參數,只需要關注action 、 x 、y 三個參數即可。
- action :事件是按下還是抬起,0 表示按下,1 表示抬起。
- x、y:表示當前事件觸發的X軸和Y軸的坐標。
也就是說,兩個 DispatchPointer 命令加在一起,分別表示 按下 和 抬起 ,一組按下和抬起,就代表了一次點擊操作,其余的參數,統一設置為 0 即可。
2、按鍵消息(DispatchKey)
DispatchKey 主要是用于發送一些 Android 標準的 EventKey 按鍵消息。只需要傳遞對應的值就好了。
具體的鍵值,可以通過官網查詢:
https://developer.android.com/reference/android/view/KeyEvent.html
DispatchKey 消息的方法前面和 DispatchPointer 一樣,所以同樣也只需要關注 action、x、y 三個參數即可。
3、開啟關閉軟鍵盤(DispatchFlip)
DispatchFlip 命令用于打開或者關閉軟鍵盤。它的方法簽名如下:
- DispatchFlip (keyboardOpen)
其中的參數,true 表示打開,false 表示關閉。
4、打開指定的Activity(LaunchActivity)
LaunchActivity 命令用于打開任意應用的一個頁面,但是前提條件是打開的Activity 需要屬性 android:exported 被設定為true,才可以通過 LaunchActivity 打開。它的方法簽名如下:
- LaunchActivity ( pkg_name , act_name )
它的兩個參數,分別表示打開的 App 的包名和打開的 Activity 的名稱。
5、等待(UserWait)
UserWait 命令用于讓腳本中斷執行一段時間。因為是腳本自動執行,多個事件之間執行的速度會非常的快,有時候我們需要等待一段時間,讓設備響應剛才執行的事件,需要在等待一段時間之后,再繼續執行腳本,這個時候就可以使用 UserWait 。
它的方法簽名如下:
- UserWait ( sleepTime )
sleepTime 的單位是毫秒。
6、輸入字符串(DispatchString)
DispatchString 命令用于輸入一個字符串。
它的方法簽名如下:
- DispatchString( input )
沒什么好解釋的, input 就是一個字符串即可,但是 MS 對中文的支持并不好,所以盡量輸入英文的測試數據。
7、運行 Shell 命令(RunCmd)
RunCmd 命令用于在設備上運行 shell 命令。當然這些 shell 命令必須是當前待測試設備支持的 shell 命令。
它的方法簽名如下:
- RunCmd ( cmd )
參數 cmd 就是需要執行的 shell 命令。
8、鍵盤事件(DispatchPress)
DispatchPress 命令用于模擬敲擊鍵盤的事件。
它的方法簽名如下:
DispatchPress( keyName )
三、MonkeyScript的源碼分析
雖然,Google 官方并沒有提供對 MS 詳細講解的 API 文檔,但是我們是可以通過源碼來分析出 MS 支持的API的。
MS 的源碼文件是:MonkeySourceScript.java
可以在 AndroidXref 網站在線查看源代碼:
這里以 5.1.1 為例子,進行講解,其實這一塊的代碼變動非常的少,隨手找一個版本了解即可。
在源碼中,所有我們上面介紹的 API 都是以一個 static final 的形式被聲明。這里簡單就 LaunchActivity 的方法的源碼進行講解,其他的 API 其實也大同小異。
如源碼所示,LaunchActiviity 會以數組的形式接收兩個參數,分別表示 PackageName 和 Activity 的 ClassName,下面具體對應的實現,我們就不細看了。再參照上面介紹的 API ,就可以很清晰的定位出方法和參數的含義了。
四、舉個例子
介紹了 MS 的 API 和在源碼中的實現,當然需要寫個 Demo 才是一個完整的技術文章。
1、測試需要一個待測試的App
既然是為了測試,就需要一個待測試的 App ,這里簡單編寫一個頁面,模擬一個用戶登錄的操作,兩個對話框,一個表示 用戶名 一個表示 密碼,然后點擊 Login 進行登錄。這個待測試的App,無論填寫什么,都是彈出提示登錄成功,***將輸入的內容清空。
2、編寫 MonkeyScript 文件
有了待測試的 App ,我們就可以開始編寫 MonkeyScript 腳本文件了。
MS 腳本,只要是文本即可,不關心后綴是什么。一般來說,會以.script 或者 .mks來作為后綴,標識它是一個 Monkey 腳本。
MS 腳本雖然有一些指定的 API ,但是也有一些固定的腳本頭,需要寫在腳本的最前面。
- # 控制 monkey 發送消息的 Monkey 頭
- count=10
- speed=1.0
- start data>>
- # 在此之下,編寫 monkey 腳本命令
- # ...
在腳本中,腳本頭是一直不變動的,為了避免寫錯,可以直接復制粘貼最為保險。在 start data>> 之后就可以正式開始編寫 monkey 腳本了,在腳本中,使用 # 號,對單行進行注釋。
接下來就開始利用 MS 提供的 API 進行腳本的編寫。首先我們需要熟悉測試的步驟。
步驟如下:
- 啟動App。
- 點擊用戶名的輸入框,輸入 250。
- 點擊密碼的輸入框,輸入 abcdef。
- 點擊 LOGIN 按鈕,彈出 Toast 提示登錄成功。
- 此次測試結束。
按照此步驟,編寫測試腳本,如下:
- count = 1
- speed = 1.0
- start data >>
- LaunchActivity(com.example.cxmy.monkeyscriptdemo,com.example.cxmy.monkeyscriptdemo.MainActivity)
- UserWait(1000)
- # 點擊密碼框
- DispatchPointer(10000,10000,0,68,345,0,0,0,0,0,0,0)
- DispatchPointer(10000,10000,1,68,345,0,0,0,0,0,0,0)
- UserWait(100)
- DispatchPress(KEYCODE_2)
- UserWait(100)
- DispatchPress(KEYCODE_5)
- UserWait(100)
- DispatchPress(KEYCODE_0)
- UserWait(100)
- # 點擊密碼框
- DispatchPointer(10000,10000,0,68,446,0,0,0,0,0,0,0)
- DispatchPointer(10000,10000,1,68,446,0,0,0,0,0,0,0)
- UserWait(100)
- DispatchString(abcdef)
- UserWait(100)
- DispatchPointer(10000,10000,0,548,627,0,0,0,0,0,0,0)
- DispatchPointer(10000,10000,1,548,627,0,0,0,0,0,0,0)
- UserWait(100)
注意這里分別使用了 DispatchPress 和 DispatchString 來分別使用,就是為了做演示,實際你可以依賴場景選擇使用的 API 。而其中涉及到坐標點的問題,這個在后面會講解如何獲取控件的坐標點。
編寫好腳本,保存為 monkey.mks 文件,并通過 adb push 將其上傳到待測試的設備中。
- adb push monkey.mks /data/local/tmp/
然后通過 monkey -f 執行此腳本,例如下面執行 10 次。
- adb shell monkey -f /data/local/tmp/monkey.mks 10
執行完成之后,可以在控制臺,看到輸出的 Log 信息。
在執行的過程中,就可以看到 MS 會自動啟動我們待測試的 App ,然后按照我們的編寫的測試腳本,進行重復執行 10 次。
3、控件坐標點的獲取
網上很多推薦獲取坐標點的方式,是使用 android-sdk/tools 目錄下,提供的 uiautomatorviewer 工具來獲取。但是這種方式非常的繁瑣,而實際上,我們又不需要如此精確的坐標點,畢竟控件那么大,只要點擊的坐標落在控件的位置上,就滿足我們的需要。
那么我推薦另外一種更簡單的方式,來獲取當前你看見的,在待測試設備上的控件的坐標點的定位方式。那就是利用 Android 設備的開發者選項。
設置 → 開發者選項 → 指針位置 ,將這個屬性開啟之后,當手指在屏幕上滑動的時候,就可以在頂部看到當前觸摸點的 X、Y 軸的坐標,這就是我們需要的。
開發者選項不是默認可見的,你需要自行開啟開發者模式,之后再進行此操作。
五、總結
MS 提供的API非常的方便,可以利用它們做一些自動化操作。
【本文為51CTO專欄作者“張旸”的原創稿件,轉載請通過微信公眾號聯系作者獲取授權】