InstrumentationTestCase
- TouchUtilsを使ったAndroidテストでjava.lang.SecurityException:PermissionDenialが起きたときの回避方法 (30 Aug 2012 | Tags:
TouchUtilsを使ったAndroidテストでjava.lang.SecurityException:PermissionDenialが起きたときの回避方法 TouchUtilsを使ったAndroidテストでjava.lang.SecurityException:PermissionDenialが起きたときの回避方法
以前の記事では、InstrumantetionTestCaseとTouchUtilsを使ってのUIテストについて書きました。
最近、この方法でテストを実行してjava.lang.SecurityException: Permission Denialが発生して、テストに失敗する事象に悩まされたので、 回避方法を記録しておきます。
原因
この問題が発生する正確な理由はわかっていません。
特定の端末(今回の場合、私が持っていたXperia arc android2.3.4)でのみ事象の発生が確認できました。
Xperia NX, MEDIASでは同じテストケースを実行してもこの現象は確認できませんでした。
これらの状況と、logcatで確認できたエラーログから察するに、 TouchUtilsは端末によっては利用できないよう制限されているようです。
そのため、テストケース中のボタンなどのViewのクリック動作がシミュレートできずにテストが失敗したようです。
TouchUtilsを使わずにテストする方法
以前紹介した方法では、ユーザのViewのクリック動作を以下のような方法でシミュレートしました。
Activityの取得
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters// Wait for it to start... Activity mCurrentActivity = getInstrumentation().waitForMonitorWithTimeout(monitor, 5); Viewを取得して、初期状態を確認。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters// Check initial state... TextView textView = (TextView)mCurrentActivity.findViewById(jp.modal.soul.uiTestSample.R.id.mainTextView); assertEquals("Hello World, UiTestSampleActivity!", textView.getText().toString()); ボタンのクリックをシミュレート。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters// 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スレッドで実行する必要があります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters// 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(); } }); Latest post:
- OpenWhiskのScala sbtプロジェクトのgiter8テンプレートを作った
- OpenWhisk+Scalaで作るServerless Architectureとっかかり
- BluemixにPlayframeworkアプリケーションをデプロイする
- sbt、Giter8を統合するってよ
- Scala 2.12.0でSAM型
Recent Books:
- AndroidアプリのUIテスト-InstrumentationTestCase編- (20 May 2012 | Tags:
AndroidアプリのUIテスト-InstrumentationTestCase編- AndroidアプリのUIテスト-InstrumentationTestCase編-
複数のActivityに跨る画面遷移のテストを調べて、サンプルを作ってみました。
サンプルのAndroidプロジェクトとテストプロジェクトは以下に置きました。
サンプルAndroidアプリ uiTestSample
サンプルテスト uiTestSample-test
参考にしたのは以下のページ How do you test an Android application across multiple Activities?
※:参考ページでは、JUnit4を使っていますが、ここではJUnit3を使っているため一部違っています。
サンプルアプリの動作について
このサンプルでは、アプリの起動後の画面にボタンが表示され、そのボタンをクリックすると別画面に遷移します。
起動後の画面
ボタンクリックで遷移後の画面
テストの概要
このサンプルでは、アプリ起動後の画面のTextViewの内容を確認。ボタン1のクリックをエミュレートし、画面遷移後の画面のTextViewの内容を確認しています。
InstrumentationTestCase
InstrumentationTestCaseを継承したクラスを作成します。 getInstrumentation()を使うことで、現在有効になってるアクティビティを捕捉し、TouchUtilsでユーザ操作をエミュレートします。
テストの流れ
捕捉するインテント情報を設定
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters// Register UiTestSampleActivity... Instrumentation mInstrumentation = getInstrumentation(); Instrumentation.ActivityMonitor monitor = mInstrumentation.addMonitor(UiTestSampleActivity.class.getName(), null, false); 存在するInstrumentation.ActivityMonitorがヒットするまで待ちます。タイムアウト時間を設定。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters// Wait for it to start... Activity mCurrentActivity = getInstrumentation().waitForMonitorWithTimeout(monitor, 5); Viewを取得して、初期状態を確認。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters// Check initial state... TextView textView = (TextView)mCurrentActivity.findViewById(jp.modal.soul.uiTestSample.R.id.mainTextView); assertEquals("Hello World, UiTestSampleActivity!", textView.getText().toString()); ボタンのクリックをエミュレート。
再度Activityを取得。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters// Wait for transited page to start... mCurrentActivity = getInstrumentation().waitForMonitorWithTimeout(monitor, 5); 画面遷移後の表示を確認。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters// Check transited state... textView = (TextView)mCurrentActivity.findViewById(jp.modal.soul.uiTestSample.R.id.transitedTextView); assertEquals(textView.getText().toString(), "Transited."); まとめ
TouchUtilsを使えば、このほかにもドラッグ、スクロール、長押し等色々エミュレートでき、UIスレッドを意識しないで書けるので、アプリのハッピーパスのテストくらいであれば簡単に書けそうです。
LinkLatest post:
- OpenWhiskのScala sbtプロジェクトのgiter8テンプレートを作った
- OpenWhisk+Scalaで作るServerless Architectureとっかかり
- BluemixにPlayframeworkアプリケーションをデプロイする
- sbt、Giter8を統合するってよ
- Scala 2.12.0でSAM型
Recent Books: