monkeyrunner

La herramienta monkeyrunner proporciona una API para escribir programas que controlan un emulador o dispositivo Android fuera de código de Android. Con monkeyrunner, puedes escribir un programa de Python que instale una aplicación para Android o un paquete de prueba, lo ejecute, le envíe combinaciones de teclas, tome capturas de pantalla de su interfaz de usuario y almacene esas capturas en la estación de trabajo. La herramienta monkeyrunner está diseñada principalmente para probar aplicaciones y dispositivos a nivel funcional o del marco de trabajo, así como para ejecutar paquetes de pruebas de unidades, aunque puedes usarla con otros fines.

La herramienta monkeyrunner no está relacionada con Exerciser Monkey para IU/aplicaciones, también conocida como herramienta monkey. La herramienta monkey se ejecuta directamente en la shell adb del dispositivo o emulador, y genera flujos pseudoaleatorios de eventos del usuario y del sistema. En comparación, la herramienta monkeyrunner controla los dispositivos y emuladores desde una estación de trabajo mediante el envío de comandos y eventos específicos desde una API.

La herramienta monkeyrunner proporciona estas funciones únicas para pruebas de Android:

  • Control de varios dispositivos: la API de monkeyrunner puede aplicar uno o más paquetes de pruebas en varios dispositivos o emuladores. Puedes conectar físicamente todos los dispositivos o iniciar todos los emuladores a la vez (o ambos), conectar cada uno de forma programática y luego ejecutar una o más pruebas. También puedes iniciar la configuración del emulador de forma programática, ejecutar una o más pruebas, y luego apagar el emulador.
  • Pruebas funcionales: monkeyrunner puede ejecutar una prueba automatizada de inicio a fin de una aplicación para Android. Debes proporcionar los valores de entrada con combinaciones de teclas o eventos táctiles, y visualizar los resultados como capturas de pantalla.
  • Pruebas de regresión: monkeyrunner puede probar la estabilidad de la aplicación ejecutándola y comparando las capturas de pantalla resultantes con un conjunto de capturas que se sabe que son correctas.
  • Automatización extensible: Dado que monkeyrunner es un kit de herramientas de API, puedes desarrollar un sistema completo de módulos y programas basados en Python para controlar dispositivos Android. Además de usar la API de monkeyrunner, puedes usar los módulos estándar os y subprocess de Python para llamar a las herramientas de Android, como Android Debug Bridge.

    También puedes agregar tus propias clases a la API de monkeyrunner. Eso se describe con mayor detalle en la sección Cómo ampliar monkeyrunner con complementos.

La herramienta monkeyrunner usa Jython, una implementación de Python que utiliza el lenguaje de programación Java. Jython permite que la API de monkeyrunner interactúe fácilmente con el framework de Android. Con Jython, puedes usar la sintaxis de Python para acceder a las constantes, las clases y los métodos de la API.

Un programa monkeyrunner simple

Este es un programa monkeyrunner simple que se conecta a un dispositivo y crea un objeto MonkeyDevice. Mediante el objeto MonkeyDevice, el programa instala un paquete de aplicación para Android, ejecuta una de las actividades y envía los eventos de clave a la actividad. El programa luego toma una captura de pantalla del resultado y crea un objeto MonkeyImage. A partir de este objeto, se escribe un archivo .png que contiene la captura de pantalla.

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

La API de monkeyrunner

La API de monkeyrunner está contenida en tres módulos del paquete com.android.monkeyrunner:

  • MonkeyRunner: Es una clase de métodos de utilidad para programas de monkeyrunner. Esta clase proporciona un método para conectar monkeyrunner a un dispositivo o emulador. También proporciona métodos que permiten crear IU para un programa monkeyrunner y para mostrar la ayuda integrada.
  • MonkeyDevice: Representa un dispositivo o emulador. Esta clase proporciona métodos para instalar y desinstalar paquetes, iniciar una actividad y enviar eventos táctiles o del teclado a una aplicación. También debes usar esta clase para ejecutar paquetes de prueba.
  • MonkeyImage: Representa una imagen de captura de pantalla. Esta clase proporciona métodos para capturar pantallas, convertir imágenes de mapas de bits a varios formatos, comparar dos objetos de MonkeyImage y escribir una imagen en un archivo.

En un programa Python, accedes a cada clase como un módulo de Python. La herramienta monkeyrunner no importa automáticamente estos módulos. Para importar un módulo, usa la declaración from de Python:

from com.android.monkeyrunner import <module>

donde <module> es el nombre de clase que quieres importar. Puedes importar más de un módulo en la misma declaración from. Para ello, separa los nombres de módulos con comas.

Cómo ejecutar monkeyrunner

Puedes ejecutar programas de monkeyrunner desde un archivo o ingresar declaraciones de monkeyrunner en una sesión interactiva. En ambos casos, debes invocar el comando monkeyrunner, que se encuentra en el subdirectorio tools/ del directorio del SDK. Si proporcionas un nombre de archivo como argumento, el comando monkeyrunner ejecutará el contenido del archivo como un programa de Python. De lo contrario, iniciará una sesión interactiva.

La sintaxis del comando monkeyrunner es

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

En la tabla 1, se explican las marcas y los argumentos.

Tabla 1: Marcas y argumentos de monkeyrunner

Argumento Descripción
-plugin <plugin_jar> Opcional: Especifica un archivo .jar que contenga un complemento para monkeyrunner. Si quieres obtener más información sobre los complementos de monkeyrunner, consulta Cómo ampliar monkeyrunner con complementos. Para especificar más de un archivo, incluye el argumento varias veces.
<program_filename> Si proporcionas este argumento, el comando monkeyrunner ejecutará el contenido del archivo como un programa de Python. Si no lo proporcionas, el comando iniciará una sesión interactiva.
<program_options> Opcional: Marcas y argumentos para el programa en <program_file>.

Ayuda integrada de monkeyrunner

Para generar una referencia de API para monkeyrunner, ejecuta lo siguiente:

monkeyrunner help.py <format> <outfile>

Los argumentos son:

  • <format> es text para salida de texto sin formato, o html para salida HTML.
  • <outfile> es un nombre de ruta de acceso completo para el archivo de salida.

Cómo ampliar monkeyrunner con complementos

Puedes ampliar la API de monkeyrunner con clases escritas en el lenguaje de programación Java y compilarla en uno o más archivos .jar. Puedes usar esta función para ampliar la API de monkeyrunner con tus propias clases o para ampliar las clases existentes. También puedes usar esta función para inicializar el entorno de monkeyrunner.

A fin de proporcionar un complemento para monkeyrunner, invoca el comando monkeyrunner con el argumento -plugin <plugin_jar> que se describe en la tabla 1.

En el código del complemento, puedes importar y ampliar las clases principales de monkeyrunner MonkeyDevice, MonkeyImage y MonkeyRunner en com.android.monkeyrunner (consulta laAPI de monkeyrunner).

Ten en cuenta que los complementos no te brindan acceso al SDK de Android. No puedes importar paquetes como com.android.app. Eso se debe a que monkeyrunner interactúa con el dispositivo o el emulador por debajo del nivel de las API de framework.

La clase de inicio del complemento

El archivo .jar de un complemento puede especificar una clase cuya instancia se crea antes de que se inicie el procesamiento de la secuencia de comandos. Para especificar esta clase, agrega la clave MonkeyRunnerStartupRunner al manifiesto del archivo .jar. El valor debe ser el nombre de la clase que se ejecuta en el inicio. En el siguiente fragmento, se muestra cómo hacer esto dentro de una secuencia de comandos de compilación ant:

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

Para obtener acceso al entorno de ejecución de monkeyrunner, la clase de inicio puede implementar com.google.common.base.Predicate<PythonInterpreter>. Por ejemplo, esta clase configura algunas variables en el espacio de nombres predeterminado:

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