Monkeyrunner

Das alte monkeyrunner-Tool bietet eine API zum Schreiben von Programmen, die ein Android-Gerät oder einen Emulator außerhalb von Android-Code steuern.

Das monkeyrunner-Tool wurde in erster Linie zum Testen von Apps und Geräten auf Funktions-/Framework-Ebene und zum Ausführen von Einheitentest-Suites entwickelt. Sie können es aber auch für andere Zwecke verwenden. Mit monkeyrunner können Sie ein Python-Programm schreiben, das eine Android-App oder ein Testpaket installiert, ausführt, Tastaturanschläge an das Programm sendet, Screenshots der Benutzeroberfläche macht und Screenshots auf der Workstation speichert.

Achtung: Die monkeyrunner API wird nicht gepflegt. Wir empfehlen stattdessen die Verwendung des App-Crawlers oder des Test-Frameworks UI Automator.

Das monkeyrunner-Tool ist nicht mit dem UI/Application Trainr Monkey, auch als monkey-Tool bekannt, verbunden. Das monkey-Tool wird in einer adb-Shell direkt auf dem Gerät oder Emulator ausgeführt und generiert pseudozufällige Streams von Nutzer- und Systemereignissen. Im Vergleich dazu steuert das monkeyrunner-Tool Geräte und Emulatoren über eine Workstation, indem bestimmte Befehle und Ereignisse von einer API gesendet werden.

Das monkeyrunner-Tool bietet folgende Funktionen für Android-Tests:

  • Steuerung für mehrere Geräte: Die monkeyrunner API kann eine oder mehrere Testsuiten auf mehrere Geräte oder Emulatoren anwenden. Sie können alle Geräte physisch anhängen oder alle oder beide Emulatoren gleichzeitig starten, eine Verbindung zu jedem einzelnen Gerät der Reihe nach programmatisch herstellen und dann einen oder mehrere Tests ausführen. Sie können die Konfiguration eines Emulators auch programmatisch starten, einen oder mehrere Tests ausführen und dann den Emulator beenden.
  • Funktionstests: Mit monkeyrunner kann ein automatischer Start-zu-Ende-Test einer Android-App durchgeführt werden. Sie stellen Eingabewerte über Tastaturanschläge oder Touch-Ereignisse bereit und sehen die Ergebnisse als Screenshots an.
  • Regressionstests: monkeyrunner kann die Anwendungsstabilität testen. Dazu wird eine Anwendung ausgeführt und die Ausgabe-Screenshots mit einer Reihe bekannter, korrekter Screenshots verglichen.
  • Erweiterbare Automatisierung: Da monkeyrunner ein API-Toolkit ist, können Sie ein System aus Python-basierten Modulen und Programmen zur Steuerung von Android-Geräten entwickeln. Neben der monkeyrunner API selbst kannst du auch die standardmäßigen Python-Module os und subprocess zum Aufrufen von Android-Tools wie Android Debug Bridge nutzen.

    Sie können der monkeyrunner API auch eigene Klassen hinzufügen. Dies wird im Abschnitt monkeyrunner mit Plug-ins erweitern ausführlicher beschrieben.

Das monkeyrunner-Tool verwendet Jython, eine Implementierung von Python, die die Programmiersprache Java verwendet. Mit Jython kann die monkeyrunner API problemlos mit dem Android-Framework interagieren. Bei Jython können Sie die Python-Syntax verwenden, um auf die Konstanten, Klassen und Methoden der API zuzugreifen.

Ein einfaches Monkeyrunner-Programm

Hier ist ein einfaches monkeyrunner-Programm, das eine Verbindung zu einem Gerät herstellt und ein MonkeyDevice-Objekt erstellt. Mithilfe des MonkeyDevice-Objekts installiert das Programm ein Android-Anwendungspaket, führt eine seiner Aktivitäten aus und sendet Schlüsselereignisse an die Aktivität. Das Programm macht dann einen Screenshot des Ergebnisses und erstellt dabei ein MonkeyImage-Objekt. Aus diesem Objekt gibt das Programm eine PNG-Datei aus, die den Screenshot enthält.

# 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
# whether 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')

Die monkeyrunner API

Die monkeyrunner API ist im Paket com.android.monkeyrunner in drei Modulen enthalten:

  • MonkeyRunner: Eine Klasse von Dienstprogrammmethoden für monkeyrunner-Programme. Diese Klasse stellt eine Methode zum Verbinden von monkeyrunner mit einem Gerät oder Emulator bereit. Außerdem finden Sie darin Methoden zum Erstellen von UIs für ein monkeyrunner-Programm und zum Anzeigen der integrierten Hilfe.
  • MonkeyDevice: Steht für ein Gerät oder einen Emulator. Diese Klasse bietet Methoden zum Installieren und Deinstallieren von Paketen, zum Starten einer Aktivität und zum Senden von Tastatur- oder Touch-Ereignissen an eine App. Sie verwenden diese Klasse auch zum Ausführen von Testpaketen.
  • MonkeyImage: Stellt ein Bildschirmaufnahmebild dar. Diese Klasse bietet Methoden zum Erfassen von Bildschirmen, zum Konvertieren von Bitmapbildern in verschiedene Formate, zum Vergleichen von zwei MonkeyImage-Objekten und zum Schreiben eines Bildes in eine Datei.

In einem Python-Programm greifen Sie auf jede Klasse als Python-Modul zu. Das monkeyrunner-Tool importiert diese Module nicht automatisch. Verwenden Sie die Python-Anweisung from, um ein Modul zu importieren:

from com.android.monkeyrunner import <module>

Dabei ist <module> der Name der Klasse, die Sie importieren möchten. Sie können mehrere Module in dieselbe from-Anweisung importieren. Trennen Sie dafür die Modulnamen durch Kommas.

Monkeyrunner

Sie können monkeyrunner-Programme entweder über eine Datei ausführen oder monkeyrunner-Anweisungen in einer interaktiven Sitzung eingeben. Dazu rufen Sie den Befehl monkeyrunner auf, der sich im Unterverzeichnis tools/ Ihres SDK-Verzeichnisses befindet. Wenn Sie einen Dateinamen als Argument angeben, führt der Befehl monkeyrunner den Inhalt der Datei als Python-Programm aus. Andernfalls startet er eine interaktive Sitzung.

Dies ist die Syntax des Befehls monkeyrunner:

monkeyrunner -plugin <plugin_jar> <program_filename> <program_options>

In Tabelle 1 werden die Flags und Argumente für monkeyrunner erläutert.

Tabelle 1 monkeyrunner-Flags und -Argumente

Argumentation Beschreibung
-plugin <plugin_jar> (Optional) Gibt eine JAR-Datei mit einem Plug-in für monkeyrunner an. Weitere Informationen zu monkeyrunner-Plug-ins finden Sie im Abschnitt monkeyrunner mit Plug-ins erweitern. Wenn Sie mehrere Dateien angeben möchten, fügen Sie das Argument mehrmals ein.
<program_filename> Wenn Sie dieses Argument angeben, führt der Befehl monkeyrunner den Inhalt der Datei als Python-Programm aus. Andernfalls startet der Befehl eine interaktive Sitzung.
<program_options> (Optional) Flags und Argumente für das Programm in <program_file>.

Integrierte Hilfe zu Monkeyrunner

Mit dem folgenden Befehl können Sie eine API-Referenz für monkeyrunner generieren:

monkeyrunner help.py <format> <outfile>

Die Argumente sind:

  • <format> ist entweder text für die Nur-Text-Ausgabe oder html für die HTML-Ausgabe.
  • <outfile> ist ein pfadqualifizierter Name für die Ausgabedatei.

Monkeyrunner mit Plug-ins erweitern

Sie können die monkeyrunner API mit Klassen erweitern, die Sie in Java schreiben, und diese in eine oder mehrere JAR-Dateien integrieren. Sie können dieses Feature verwenden, um die monkeyrunner API mit Ihren eigenen Klassen zu erweitern oder um die vorhandenen Klassen zu erweitern. Sie können dieses Feature auch verwenden, um die monkeyrunner-Umgebung zu initialisieren.

Um monkeyrunner ein Plug-in bereitzustellen, rufen Sie den Befehl monkeyrunner mit dem Argument -plugin <plugin_jar> auf, das in Tabelle 1 beschrieben wird.

In deinem Plug-in-Code kannst du die monkeyrunner-Hauptklassen MonkeyDevice, MonkeyImage und MonkeyRunner in com.android.monkeyrunner importieren und erweitern (siehe Abschnitt zur monkeyrunner API).

Beachten Sie, dass Plug-ins keinen Zugriff auf das Android SDK gewähren. Pakete wie com.android.app können nicht importiert werden. Das liegt daran, dass monkeyrunner mit dem Gerät oder Emulator unter dem Niveau der Framework-APIs interagiert.

Die Plug-in-Startklasse

In der JAR-Datei für ein Plug-in kann eine Klasse angegeben werden, die vor Beginn der Skriptverarbeitung instanziiert wird. Fügen Sie dem Manifest der JAR-Datei den Schlüssel MonkeyRunnerStartupRunner hinzu, um diese Klasse anzugeben. Verwenden Sie als Wert den Namen der Klasse, die beim Start ausgeführt werden soll. Das folgende Snippet zeigt, wie das in einem ant-Build-Skript funktioniert:

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


Die Startklasse kann com.google.common.base.Predicate<PythonInterpreter> implementieren, um Zugriff auf die Laufzeitumgebung des monkeyrunner-Tools zu erhalten. Diese Klasse richtet beispielsweise einige Variablen im Standard-Namespace ein:

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;
    }
}