以前の記事では、InstrumantetionTestCaseとTouchUtilsを使ってのUIテストについて書きました。

最近、この方法でテストを実行してjava.lang.SecurityException: Permission Denialが発生して、テストに失敗する事象に悩まされたので、 回避方法を記録しておきます。

原因

この問題が発生する正確な理由はわかっていません。

特定の端末(今回の場合、私が持っていたXperia arc android2.3.4)でのみ事象の発生が確認できました。

Xperia NX, MEDIASでは同じテストケースを実行してもこの現象は確認できませんでした。

これらの状況と、logcatで確認できたエラーログから察するに、 TouchUtilsは端末によっては利用できないよう制限されているようです。

そのため、テストケース中のボタンなどのViewのクリック動作がシミュレートできずにテストが失敗したようです。


TouchUtilsを使わずにテストする方法

以前紹介した方法では、ユーザのViewのクリック動作を以下のような方法でシミュレートしました。

Activityの取得

// Wait for it to start...
Activity mCurrentActivity = getInstrumentation().waitForMonitorWithTimeout(monitor, 5);

Viewを取得して、初期状態を確認。

// Check initial state...
TextView textView = (TextView)mCurrentActivity.findViewById(jp.modal.soul.uiTestSample.R.id.mainTextView);
assertEquals("Hello World, UiTestSampleActivity!", textView.getText().toString());

ボタンのクリックをシミュレート。

// Check initial state...
TextView textView = (TextView)mCurrentActivity.findViewById(jp.modal.soul.uiTestSample.R.id.mainTextView);
assertEquals("Hello World, UiTestSampleActivity!", textView.getText().toString());

performClick()を使った回避方法

上記のクリックのシミュレートに使用したTouchUtilsの代わりに、performClick()を使います。

※この場合、clickPerformは明示的にUIスレッドで実行する必要があります。

// Wait for it to start...
final Activity mCurrentActivity = getInstrumentation().waitForMonitorWithTimeout(monitor, 5);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
View v = mCurrentActivity.findViewById(jp.modal.soul.uiTestSample.R.id.mainTextView);
v.performClick();
}
});