MonkeyRunner

舊版 MonkeyRunner 工具提供 API 編寫程式,讓您從 Android 程式碼以外的位置控制 Android 裝置或模擬器。使用 MonkeyRunner 即可編寫 Python 程式,以安裝 Android 應用程式或測試套件、執行套件、傳送按鍵動作、擷取使用者介面的螢幕截圖,並將螢幕截圖儲存到工作站。MonkeyRunner 工具主要用於在功能/架構層級測試應用程式和裝置,以及執行單元測試套件,但您可以將此內容用於其他用途。

注意:MonkeyRunner API 未維護。如適用,我們建議改用 UI Automator 測試架構。

MonkeyRunner 工具與 UI/Application Exerciser Monkey 無關,也稱為 monkey 工具。monkey 工具會直接在裝置或模擬器的 adb 殼層中執行,並產生使用者和系統事件的虛擬隨機串流。相較之下,MonkeyRunner 工具會從 API 傳送特定指令和事件,藉此控制工作站中的裝置和模擬器。

MonkeyRunner 工具為 Android 測試提供下列獨家功能:

  • 多重裝置控制:MonkeyRunner API 可以在多個裝置或模擬器中套用一或多個測試套件。您可以實際連接所有裝置,也可以一次啟動所有模擬器 (也可以同時採用這兩種裝置),然後以程式輔助方式連接至所有裝置,執行一或多個測試。您也可以用程式輔助方式啟動模擬器設定,執行一或多個測試,然後關閉模擬器。
  • 功能測試:MonkeyRunner 可針對 Android 應用程式執行自動化的開始至結束測試。使用按鍵動作或觸控事件提供輸入值,並以螢幕截圖查看結果。
  • 迴歸測試 - MonkeyRunner 會執行應用程式,將輸出內容的螢幕截圖與一組已知的正確螢幕截圖進行比較,藉此測試應用程式的穩定性。
  • 可擴充的自動化 - 由於 MonkeyRunner 是 API 工具包,因此您可以開發整套以 Python 為基礎的模組和程式來控制 Android 裝置。除了使用 MonkeyRunner API,您也可以使用標準 Python ossubprocess 模組呼叫 Android 工具,例如 Android Debug Bridge

    您也可以將專屬類別新增至 MonkeyRunner API。詳情請參閱「使用外掛程式擴充 MonkeyRunner」一節。

MonkeyRunner 工具使用 Jython,這是使用 Java 程式設計語言的 Python 實作。Jython 可讓 MonkeyRunner API 輕鬆與 Android 架構互動。您可透過 Jython 使用 Python 語法來存取 API 的常數、類別和方法。

簡易的 MonkeyRunner 程式

下列是連結至裝置的簡單 MonkeyRunner 程式,會建立 MonkeyDevice 物件。程式會使用 MonkeyDevice 物件安裝 Android 應用程式套件,執行其中一項活動,並將重要事件傳送至活動。程式接著會擷取結果的螢幕截圖,並建立 MonkeyImage 物件。程式會向這個物件寫入包含螢幕截圖的 .png 檔案。

# Imports the monkeyrunner modules used by this program
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice

# Connects to the current device, returning a MonkeyDevice object
device = 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('myproject/bin/MyApplication.apk')

# sets a variable with the package's internal name
package = 'com.example.android.myapplication'

# sets a variable with the name of an Activity in the package
activity = 'com.example.android.myapplication.MainActivity'

# sets the name of the component to start
runComponent = package + '/' + activity

# Runs the component
device.startActivity(component=runComponent)

# Presses the Menu button
device.press('KEYCODE_MENU', MonkeyDevice.DOWN_AND_UP)

# Takes a screenshot
result = device.takeSnapshot()

# Writes the screenshot to a file
result.writeToFile('myproject/shot1.png','png')

MonkeyRunner API

MonkeyRunner API 包含在 com.android.monkeyrunner 套件的三個模組中:

  • MonkeyRunner:適用於 MonkeyRunner 程式的公用程式方法。這個類別提供將 MonkeyRunner 連線至裝置或模擬器的方法。並提供為 MonkeyRunner 程式建立使用者介面以及顯示內建說明的方法。
  • MonkeyDevice:代表裝置或模擬器。這個類別提供安裝及解除安裝套件、開始活動,以及將鍵盤或觸控事件傳送到應用程式的方法。您也可以使用這個類別執行測試套件。
  • MonkeyImage:代表螢幕畫面擷取圖片。這個類別提供擷取螢幕畫面、將點陣圖圖片轉換為不同格式、比較兩個 MonkeyImage 物件,以及將圖片寫入檔案的方法。

在 Python 程式中,您可以使用 Python 模組存取每個類別。MonkeyRunner 工具不會自動匯入這些模組。如要匯入模組,請使用 Python from 陳述式:

from com.android.monkeyrunner import <module>

其中 <module> 是您要匯入的類別名稱。您可以在同一個 from 陳述式中匯入多個模組,只需以半形逗號分隔模組名稱即可。

執行 MonkeyRunner

您可以在檔案中執行 MonkeyRunner 程式,或是在互動工作階段中輸入 MonkeyRunner 陳述式。您可以叫用 monkeyrunner 指令,它位於 SDK 目錄的 tools/ 子目錄。如果您提供檔案名稱做為引數,monkeyrunner 指令會以 Python 程式執行檔案內容;否則,事件會啟動互動式工作階段。

monkeyrunner 指令的語法為

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 內建說明

您可執行以下命令為 MonkeyRunner 產生 API 參考資料:

monkeyrunner help.py <format> <outfile>

引數如下:

  • <format> 是純文字輸出的 text,或用於 HTML 輸出的 html
  • <outfile> 是輸出檔案的路徑認證名稱。

使用外掛程式擴充 MonkeyRunner

您可使用 Java 程式設計語言撰寫類別,並建構一或多個 .jar 檔案,以擴充 MonkeyRunner API。您可以透過這項功能將 MonkeyRunner API 擴充成專屬類別,或是擴充現有類別。這項功能也可以進行 MonkeyRunner 環境初始化。

如要提供 MonkeyRunner 外掛程式,請依表 1 所述,使用 -plugin <plugin_jar> 引數叫用 monkeyrunner 指令。

在外掛程式程式碼中,您可在 com.android.monkeyrunner 匯入及擴充主要的 MonkeyRunner 類別 MonkeyDeviceMonkeyImageMonkeyRunner (請參閱 「MonkeyRunner API」)。

請注意,外掛程式無法讓您存取 Android SDK。您無法匯入 com.android.app 等套件。這是因為 MonkeyRunner 會與架構 API 層級下方的裝置或模擬器互動。

外掛程式啟動類別

外掛程式的 .jar 檔案可以指定在指令碼處理開始前執行個體化的類別。如您指定這個類別,請將金鑰 MonkeyRunnerStartupRunner 新增至 .jar 檔案的資訊清單。這個值應為啟動時執行的類別名稱。下列程式碼片段說明如何在 ant 建構指令碼中執行此操作:

<jar jarfile="myplugin" basedir="${build.dir}">
<manifest>
<attribute name="MonkeyRunnerStartupRunner" value="com.myapp.myplugin"/>
</manifest>
</jar>

如要存取 MonkeyRunner 的執行階段環境,啟動類別可實作 com.google.common.base.Predicate<PythonInterpreter>。例如,下列類別會在預設命名空間中設定部分變數:

Kotlin

package com.android.example

import com.google.common.base.Predicate
import org.python.util.PythonInterpreter

class Main: Predicate<PythonInterpreter> {

    override fun apply(anInterpreter: PythonInterpreter): Boolean {
        /*
         * Examples of creating and initializing variables in the monkeyrunner environment's
         * namespace. During execution, the monkeyrunner program can refer to the variables
         * "newtest" and "use_emulator"
         *
         */
        anInterpreter.set("newtest", "enabled")
        anInterpreter.set("use_emulator", 1)
        return true
    }
}

Java

package com.android.example;

import com.google.common.base.Predicate;
import org.python.util.PythonInterpreter;

public class Main implements Predicate<PythonInterpreter> {
    @Override
    public boolean apply(PythonInterpreter anInterpreter) {

        /*
        * Examples of creating and initializing variables in the monkeyrunner environment's
        * namespace. During execution, the monkeyrunner program can refer to the variables "newtest"
        * and "use_emulator"
        *
        */
        anInterpreter.set("newtest", "enabled");
        anInterpreter.set("use_emulator", 1);

        return true;
    }
}