Monkeyrunner

Das alte monkeyrunner-Tool bietet eine API zum Schreiben von Programmen, mit denen ein Android-Gerät oder ‑Emulator außerhalb von Android-Code gesteuert werden kann.

Das monkeyrunner-Tool ist in erster Linie für das Testen von Apps und Geräten auf der funktionalen/Framework-Ebene und für das Ausführen von Unittest-Suites konzipiert, kann aber auch für andere Zwecke verwendet werden. Mit monkeyrunner können Sie ein Python-Programm schreiben, das eine Android-App oder ein Testpaket installiert, ausführt, Tasteneingaben an die App sendet, Screenshots der Benutzeroberfläche erstellt und Screenshots auf der Workstation speichert.

Achtung:Die monkeyrunner API wird nicht mehr gewartet. Wir empfehlen stattdessen die Verwendung des UI Automator-Testframeworks.

Das Tool monkeyrunner hat nichts mit dem UI/Application Exerciser Monkey zu tun, auch bekannt als das Tool monkey. Das Tool monkey 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 von einer Arbeitsstation aus, indem es bestimmte Befehle und Ereignisse über eine API sendet.

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

  • Steuerung mehrerer Geräte: Mit der monkeyrunner API können ein oder mehrere Testsätze auf mehreren Geräten oder Emulatoren ausgeführt werden. Sie können alle Geräte physisch anschließen oder alle Emulatoren gleichzeitig starten (oder beides), sich nacheinander programmatisch mit jedem verbinden und dann einen oder mehrere Tests ausführen. Sie können auch ein Emulator-Konfigurationsprogramm programmatisch starten, einen oder mehrere Tests ausführen und den Emulator dann herunterfahren.
  • Funktionstests: Mit monkeyrunner kann ein automatisierter End-to-End-Test einer Android-App durchgeführt werden. Sie geben Eingabewerte über Tastatureingaben oder Touch-Ereignisse an und sehen die Ergebnisse als Screenshots.
  • Regressionstests: Mit monkeyrunner kann die Stabilität einer App getestet werden, indem eine App ausgeführt und ihre Ausgabescreenshots mit einer Reihe von Screenshots verglichen werden, die als korrekt bekannt sind.
  • 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 Verwendung der monkeyrunner API selbst können Sie die Standardmodule os und subprocess von Python verwenden, um Android-Tools wie die Android Debug Bridge aufzurufen.

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

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

Einfaches monkeyrunner-Programm

Hier ist ein einfaches monkeyrunner-Programm, das eine Verbindung zu einem Gerät herstellt und ein MonkeyDevice-Objekt erstellt. Mit dem MonkeyDevice-Objekt installiert das Programm ein Android-Anwendungspaket, führt eine seiner Aktivitäten aus und sendet Schlüsselereignisse an die Aktivität. Das Programm erstellt dann einen Screenshot des Ergebnisses und damit ein MonkeyImage-Objekt. Aus diesem Objekt schreibt das Programm eine PNG-Datei mit dem Screenshot.

# 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 in drei Modulen im Paket com.android.monkeyrunner enthalten:

  • MonkeyRunner: Eine Klasse von Hilfsmethoden für monkeyrunner-Programme. Diese Klasse bietet eine Methode zum Verbinden von monkeyrunner mit einem Gerät oder Emulator. Außerdem bietet sie Methoden zum Erstellen von Benutzeroberflächen für ein monkeyrunner-Programm und zum Anzeigen der integrierten Hilfe.
  • MonkeyDevice: Stellt ein Gerät oder einen Emulator dar. 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 Screenshot-Bild dar. Diese Klasse bietet Methoden zum Erfassen von Bildschirmen, zum Konvertieren von Bitmap-Bildern 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. Mit dem monkeyrunner-Tool werden diese Module nicht automatisch importiert. Verwenden Sie die Python-Anweisung from, um ein Modul zu importieren:

from com.android.monkeyrunner import <module>

Dabei ist <module> der Klassenname, den Sie importieren möchten. Sie können mehr als ein Modul in derselben from-Anweisung importieren, indem Sie die Modulnamen durch Kommas trennen.

monkeyrunner ausführen

Sie können monkeyrunner-Programme entweder aus einer Datei ausführen oder monkeyrunner-Anweisungen in einer interaktiven Sitzung eingeben. Beides erfolgt durch Aufrufen des Befehls monkeyrunner, 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 wird eine interaktive Sitzung gestartet.

Die Syntax des Befehls monkeyrunner lautet so:

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

In Tabelle 1 werden die monkeyrunner-Flags und -Argumente erläutert.

Tabelle 1 monkeyrunner-Flags und -Argumente

Argument 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 mehr als eine Datei 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 wird mit dem Befehl eine interaktive Sitzung gestartet.
<program_options> Optional: Flags und Argumente für das Programm in <program_file>.

monkeyrunner-Hilfe

Sie können eine API-Referenz für monkeyrunner generieren, indem Sie Folgendes ausführen:

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 in eine oder mehrere JAR-Dateien einbinden. Mit dieser Funktion können Sie die monkeyrunner API mit eigenen Klassen erweitern oder die vorhandenen Klassen erweitern. Sie können diese Funktion auch verwenden, um die monkeyrunner-Umgebung zu initialisieren.

Wenn Sie ein Plug-in für monkeyrunner bereitstellen möchten, rufen Sie den Befehl monkeyrunner mit dem in Tabelle 1 beschriebenen Argument -plugin <plugin_jar> auf.

Im Plug-in-Code können Sie die Hauptklassen monkeyrunner MonkeyDevice, MonkeyImage und MonkeyRunner in com.android.monkeyrunner importieren und erweitern (siehe den Abschnitt zur monkeyrunner API).

Hinweis: Mit Plugins erhalten Sie keinen Zugriff auf das Android SDK. Pakete wie com.android.app können nicht importiert werden. Das liegt daran, dass monkeyrunner unterhalb der Framework-APIs mit dem Gerät oder Emulator interagiert.

Die Startklasse des Plug-ins

In der JAR-Datei für ein Plug-in kann eine Klasse angegeben werden, die instanziiert wird, bevor die Verarbeitung des Skripts beginnt. Wenn Sie diese Klasse angeben möchten, fügen Sie dem Manifest der JAR-Datei den Schlüssel MonkeyRunnerStartupRunner hinzu. Verwenden Sie für den 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>

Um auf die Laufzeitumgebung des monkeyrunner-Tools zuzugreifen, kann die Startklasse com.google.common.base.Predicate<PythonInterpreter> implementieren. In dieser Klasse werden beispielsweise einige Variablen im Standard-Namespace eingerichtet:

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