Google は、黒人コミュニティに対する人種平等の促進に取り組んでいます。取り組みを見る

monkeyrunner

monkeyrunner ツールは、Android コードの外部から Android デバイスまたはエミュレータを制御するプログラムを作成するための API を提供します。monkeyrunner を使用すると、Android アプリまたはテスト パッケージのインストールと実行、キー操作の送信、ユーザー インターフェースのスクリーンショットの取得、スクリーンショットのワークステーションへの保存を行う Python プログラムを作成できます。monkeyrunner ツールは機能 / フレームワーク レベルでアプリとデバイスをテストすることと、単体テストスイートを実行することを主な目的として設計されていますが、それ以外の目的でも自由に使用できます。

monkeyrunner ツールは、UI/Application Exerciser Monkey(別名 monkey ツール)とは無関係です。monkey ツールは、デバイスまたはエミュレータ上の adb シェル内で直接実行され、ユーザー イベントとシステム イベントの擬似ランダム ストリームを生成します。これに対して、monkeyrunner ツールは API から特定のコマンドとイベントを送信して、ワークステーションからデバイスとエミュレータを制御します。

monkeyrunner ツールは、Android のテストを行うための以下のような独自の機能を備えています。

  • 複数のデバイスの制御: monkeyrunner API は、複数のデバイスまたはエミュレータに 1 つ以上のテストスイートを適用できます。すべてのデバイスを物理的に接続するか、すべてのエミュレータを起動するか、またはその両方を行い、プログラムで順番に接続して、1 つ以上のテストを実行できます。また、エミュレータ構成をプラグラムで起動し、1 つ以上のテストを実行してからエミュレータをシャットダウンすることもできます。
  • 機能テスト: monkeyrunner は、Android アプリの起動から終了までを自動化してテストできます。キー操作またはタッチイベントの入力値を渡すと、結果がスクリーンショットとして表示されます。
  • 回帰テスト: monkeyrunner では、アプリを実行し、出力されたスクリーンショットと正常であるとわかっているスクリーンショットを比較することで、アプリの安定性をテストできます。
  • 拡張可能な自動化: monkeyrunner は API ツールキットであるため、Python ベースのモジュールとプログラムのシステム全体を開発して、Android デバイスを制御できます。monkeyrunner API 自体を使用する代わりに、Python の標準の os モジュールと subprocess モジュールを使用して、Android Debug Bridge などの Android ツールを呼び出すこともできます。

    また、monkeyrunner API に独自のクラスを追加することもできます。詳細については、プラグインを使用して monkeyrunner を拡張するセクションをご覧ください。

monkeyrunner ツールは、Java プログラミング言語を使用した Python の実装である Jython を使用しています。そのため、monkeyrunner API は Android フレームワークと簡単にやり取りできます。Jython では、Python 構文を使用して、API の定数、クラス、メソッドにアクセスできます。

シンプルな monkeyrunner プログラム

デバイスに接続して MonkeyDevice オブジェクトを作成する簡単な monkeyrunner プログラムを以下に示します。このプログラムは、MonkeyDevice オブジェクトを使用して Android アプリ パッケージをインストールし、そのアクティビティの 1 つを実行してキーイベントをアクティビティに送信します。次に、結果のスクリーンショットを取得して、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 パッケージの 3 つのモジュールに含まれています。

  • MonkeyRunner: monkeyrunner プログラム用のユーティリティ メソッドのクラス。このクラスは、monkeyrunner をデバイスまたはエミュレータに接続するためのメソッドを提供します。また、monkeyrunner プログラム用の UI を作成するメソッドと、組み込みヘルプを表示するメソッドも提供します。
  • MonkeyDevice: デバイスまたはエミュレータを表します。このクラスは、パッケージのインストールとアンインストールを行うメソッド、アクティビティを開始するメソッド、キーボード イベントまたはタッチイベントをアプリに送信するメソッドを提供します。また、このクラスを使用してテスト パッケージを実行することもできます。
  • MonkeyImage: スクリーン キャプチャの画像を表します。このクラスは、スクリーンをキャプチャするメソッド、ビットマップ画像をさまざまな形式に変換するメソッド、2 つの MonkeyImage オブジェクトを比較するメソッド、画像をファイルに書き出すメソッドを提供します。

Python プログラムでは、各クラスに Python モジュールとしてアクセスします。monkeyrunner ツールは、こうしたモジュールの自動インポートは行いません。モジュールをインポートするには、Python の from ステートメントを使用します。

from com.android.monkeyrunner import <module>

ここで、<module> はインポートするクラス名です。モジュール名をカンマで区切ると、1 つの from ステートメントで複数のモジュールをインポートできます。

monkeyrunner を実行する

monkeyrunner プログラムを実行するには、ファイルから実行するか、対話型セッションで monkeyrunner ステートメントを入力します。どちらの方法を使用する場合も、SDK ディレクトリの tools/ サブディレクトリにある monkeyrunner コマンドを呼び出します。引数としてファイル名を指定した場合、monkeyrunner コマンドはファイルの内容を Python プログラムとして実行します。それ以外の場合は、対話型セッションを開始します。

monkeyrunner コマンドの構文は以下のとおりです。

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

フラグと引数については、表 1 を参照してください。

表 1. monkeyrunner フラグと引数。

引数 説明
-plugin <plugin_jar> (任意)monkeyrunner のプラグインを含む .jar ファイルを指定します。 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 プログラミング言語で記述したクラスで monkeyrunner API を拡張し、1 つ以上の .jar ファイルに組み込むことができます。この機能を使用して、独自のクラスによる monkeyrunner API の拡張または既存のクラスの拡張を行うことができます。monkeyrunner 環境を初期化することもできます。

monkeyrunner にプラグインを組み込むには、表 1 で説明した -plugin <plugin_jar> 引数を指定して monkeyrunner コマンドを呼び出します。

プラグインのコードで、com.android.monkeyrunner 内にある monkeyrunner のメインクラス MonkeyDeviceMonkeyImage、および MonkeyRunner をインポートまたは拡張できます(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;
    }
}