UI測試注意事項
阿新 • • 發佈:2019-02-20
UI執行緒中測試
Activity執行在程式的UI執行緒裡。一旦UI初始化後,例如在Activity的onCreate()方法後,所有與UI的互動都必須執行在UI執行緒裡。當你正常執行程式時,它有許可權可以訪問這個執行緒,並且不會出現什麼特別的事情。
當你執行測試程式時,這一點發生了變化。在帶有instrumentation的類裡,你可以觸發方法在UI執行緒裡執行。其它的測試用例類不允許這麼做。為了一個完整的測試方法都在UI執行緒裡執行,你可以使用@UIThreadTest來宣告執行緒。注意,這將會在UI執行緒裡執行方法裡所有的語句。不與UI互動的方法不允許這麼做;例如,你不能觸發Instrumentation.waitForIdleSync()。
如果讓方法中的一部分程式碼執行在UI執行緒的話,建立一個匿名的Runnable物件,把程式碼放到run()方法中,然後把這個物件傳遞給appActivity.runOnUiThread(),在這裡,appActivity就是你要測試的app物件。
例如,下面的程式碼例項化了一個要測試的Activity,為Spinner請求焦點,然後傳送一個按鍵給它。注意:waitForIdleSync和sendKeys不允許在UI執行緒裡執行:
private MyActivity mActivity; // MyActivity is the class name of the app under test
private Spinner mSpinner;
...
protected void setUp() throws Exception {
super.setUp();
mInstrumentation = getInstrumentation();
mActivity = getActivity(); // get a references to the app under test
/*
* Get a reference to the main widget of the app under test, a Spinner
*/
mSpinner = (Spinner) mActivity.findViewById(com.android.demo.myactivity.R.id.Spinner01);
...
public void aTest() {
/*
* request focus for the Spinner, so that the test can send key events to it
* This request must be run on the UI thread. To do this, use the runOnUiThread method
* and pass it a Runnable that contains a call to requestFocus on the Spinner.
*/
mActivity.runOnUiThread(new Runnable() {
public void run() {
mSpinner.requestFocus();
}
});
mInstrumentation.waitForIdleSync();
this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
關閉觸屏模式
為了控制從測試程式中傳送給模擬器或裝置的按鍵事件,你必須關閉觸屏模式。如果你不這麼做,按鍵事件將被忽略。
關閉觸控模式,你需要在呼叫getActivity()啟動Activity之前呼叫ActivityInstrumentationTestCase2.setActivityTouchMode(false)。你必須在非UI執行緒中執行這個呼叫。基於這個原因,你不能在宣告有@UIThread的測試方法呼叫。可以在setUp()中呼叫。
模擬器或裝置的解鎖
你可能已經發現,如果模擬器或裝置的鍵盤保護模式使得HOME畫面不可用時,UI測試不能正常工作。這是因為應用程式不能接收sendKeys()的事件。避免這種情況最好的方式是在啟動模擬器或裝置時關閉鍵盤保護模式。
你還可以顯式地關閉鍵盤保護。這需要在manifest檔案中新增一個許可權,然後就能在程式中關閉鍵盤保護。注意,你必須在釋出程式之前移除這個,或者在釋出的程式中禁用這個功能。
在<manifest>元素下新增<uses-permission android:name=”androd.permission.DISABLE_KEYGUARD”/>。為了關閉鍵盤保護,在你測試的Activity的onCreate()方法中新增以下程式碼:
mKeyGuardManager = (KeyguardManager)getSystemService(KEYGUARD_SERVICE);
mLock = mKeyGuardManager.newKeyguardLock("activity_classname");
mLock.disableKeyguard();
這裡,activity_classname是Activity的類名。