monkeyrunner

La herramienta monkeyrunner heredada proporciona una API para escribir programas que controlan un emulador o dispositivo Android fuera del código de Android.

La herramienta monkeyrunner está diseñada principalmente para probar apps y dispositivos a nivel funcional o de framework, así como para ejecutar paquetes de pruebas de unidades, pero puedes usarla con otros fines. Con monkeyrunner, puedes escribir un programa de Python que instale una app 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.

Precaución: La API de monkeyrunner no tiene mantenimiento. En su lugar, recomendamos que uses la herramienta App Crawler o el framework de prueba UI Automator.

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 enviando comandos y eventos específicos desde una API.

La herramienta monkeyrunner proporciona estas funciones para las 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 app para Android. Debes proporcionar los valores de entrada con combinaciones de teclas o eventos táctiles, y ver los resultados como capturas de pantalla.
  • Pruebas de regresión: monkeyrunner puede probar la estabilidad de la app ejecutando una app y comparando las capturas de pantalla resultantes con un conjunto de capturas que se sabe que son correctas.
  • Automatización extensible: Como monkeyrunner es un kit de herramientas de API, puedes desarrollar un sistema 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. Esto se describe con más 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. Con el uso del 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, el programa 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
# 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')

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 IUs 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 app. 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.

Ejecuta monkeyrunner

Puedes ejecutar programas monkeyrunner desde un archivo o ingresando declaraciones 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 la siguiente:

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

En la Tabla 1, se explican las marcas y los argumentos de monkeyrunner.

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 la sección 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. De lo contrario, el comando inicia 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 la 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 de 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 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.

Si deseas 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 de complemento, puedes importar y ampliar las clases principales de monkeyrunner (MonkeyDevice, MonkeyImage y MonkeyRunner en com.android.monkeyrunner). Consulta la sección sobre la API 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 APIs 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. Para el valor, usa el nombre de la clase que se ejecuta en el inicio. En el siguiente fragmento, se muestra cómo hacerlo 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 la herramienta 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;
    }
}