Android C++開発 [2] : InstrumentedTestでUIを表示する
InstrumentedTestを使えばデバイス上でUnitTestができますが、状態や映像を表示したりするにはUIが表示できると便利です。
InstrumentedTestにActivity表示のルールを追加する
Activityのテストをするにはテストクラスに ActivityTestRule というルールを追加します。
つまりテスト実行時にこのActivityを表示するように、といったルールの定義です。
ExampleInstrumentedTest.java
@Rule public ActivityTestRule rule = new ActivityTestRule<>(MainActivity.class, true, true);
この記述を行うとビルドエラーが発生します。
なぜならInstrumentedTest実行時にこのクラスを参照する設定がされていないからです。
build.gradle の dependencies 内、 androidTestImplementation の部分に参照を追加するとビルドエラーは解消します。
build.gradle
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:rules:0.4' #コレを追加 androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' }
ActivityにUI要素を追加
実施するテストに応じてActivityに必要なUI要素を追加します。
ここでは文字列を表示する TextView を "textMessage" という名前で追加しました。
テストクラスからUI要素にアクセスする
テストクラスからActivity内のUI要素にアクセスするには、先ほど追加したActivityTestRule からActivityを取得し操作します。
ただUI要素はUIスレッドから操作する必要があるので直接操作することはできず、runOnUiThread()メソッドにアクションを渡し、非同期で実行させる必要があるのですこし面倒でした。
このようなユーティリティメソッドを作成しました。
private void showMessageOnUiThread(String message) { class ShowTextAction implements Runnable { private String message; public ShowTextAction(String message) { this.message = message; } @Override public void run() { TextView messageText = rule.getActivity().findViewById(R.id.textMessage); messageText.setText(this.message); } } this.rule.getActivity().runOnUiThread(new ShowTextAction(message)); }
テストメソッドからの呼び出し
以上の準備を行えばテストメソッド内から画面に文字列を表示することができます。
応用すれば様々な操作を行うことができます。それだけではなくこのRuleの真価はUIの自動テストが行えるところにあります。
ボタンをプッシュするといった人が行うようなアクションもシミュレートさせることができます。
さて、テストメソッドでC++から取得した文字列を表示するためにはこのような実装を行いました。
ExampleInstrumentedTest.java
@Test public void stringFromJNITest() throws InterruptedException { String message = stringFromJNI(); this.showMessageOnUiThread(message); Thread.sleep(5000); assertEquals("Hello from C++ to InstrumentedTest", message); }
実行結果はこのようになります。
C++から取得したメッセージが表示されています。
まとめ
Andoid実機で動作するInstrumentedTestで画面を表示し、UI要素にアクセスする方法をお伝えしました。
プロジェクト一式は下記にアップしています。