以前の monkeyrunner ツールには、Android コードの外部から Android デバイスまたはエミュレータを制御するプログラムを作成するための API が用意されています。
monkeyrunner ツールは主に、機能レベルやフレームワーク レベルでアプリとデバイスをテストし、単体テストスイートを実行するように設計されていますが、他の目的にも使用できます。monkeyrunner を使用すると、Android アプリまたはテスト パッケージのインストールと実行、キー操作の送信、ユーザー インターフェースのスクリーンショットの取得、スクリーンショットのワークステーションへの保存を行う Python プログラムを作成できます。
注意: monkeyrunner API はメンテナンスされていません。代わりに、UI Automator テスト フレームワークを使用することをおすすめします。
monkeyrunner ツールは、UI/Application Exerciser Monkey(別名 monkey ツール)とは無関係です。monkey ツールは、デバイスまたはエミュレータ上の adb シェル内で直接実行され、ユーザー イベントとシステム イベントの擬似ランダム ストリームを生成します。これに対して、monkeyrunner ツールは API から特定のコマンドとイベントを送信して、ワークステーションからデバイスとエミュレータを制御します。
monkeyrunner ツールは Android のテストを行うために以下の機能を備えています。
-
複数のデバイスの制御:
monkeyrunnerAPI は、複数のデバイスまたはエミュレータに 1 つ以上のテストスイートを適用できます。一度にすべてのデバイスを物理的に接続するかすべてのエミュレータを起動し(またはその両方)、プログラムで順番に接続して、複数のテストを実行できます。また、エミュレータ構成をプラグラムで起動し、1 つ以上のテストを実行してからエミュレータをシャットダウンすることもできます。 -
機能テスト:
monkeyrunnerは、Android アプリの起動から終了までを自動化してテストできます。キー操作またはタッチイベントの入力値を渡すと、結果がスクリーンショットとして表示されます。 -
回帰テスト:
monkeyrunnerでは、アプリを実行し、出力されたスクリーンショットと正常であるとわかっているスクリーンショットと比較することで、アプリの安定性をテストできます。 -
拡張可能な自動化:
monkeyrunnerは API ツールキットであるため、Python ベースのモジュールとプログラムのシステムを開発して、Android デバイスを制御できます。monkeyrunnerAPI 自体を使用する代わりに、Python の標準のosモジュールとsubprocessモジュールを使用して、Android Debug Bridge などの Android ツールを呼び出すこともできます。monkeyrunnerAPI に独自のクラスを追加することもできます。詳しくは、プラグインを使用して 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 # 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')
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>
monkeyrunner のフラグと引数については、表 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 のメインクラス MonkeyDevice、MonkeyImage、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; } }