[android test] Activity測試

來源:互聯網
上載者:User

原文地址:https://developer.android.com/tools/testing/activity_testing.html

Activity測試非常依賴於android instrumentation架構,不像其它組件,Activity有比較複雜的基於回調方法的生命週期,這些方法不能被直接調用,除了instrumentation。同時,程式中向UI發送事件的唯一途徑就是instrumentation。

本文檔描述如何用 instrumentation和其它測試組件來測試Activity。文檔假設你已經閱讀了Testing Fundamentals,它對android 測試和 instrumentation做了基本介紹。

Activity測試API

Activity測試API的基類是InstrumentationTestCase,它為你使用的test case 子類提供了instrumentation。

對於Activity測試,該基類提供了如下功能:

  • 生命週期控制:通過instrumentation,你可以使用test case類提供的方法來啟動、暫停、銷毀被測試的Activity。
  • 注入依賴:instrumentation讓你可以建立類比的例如Context、Application的系統組件,並且用它們來啟動被測試Activity。這可以協助你控制測試環境同時與實際系統隔離開。你也可以建立自訂的Intent並且用它來啟動Activity。
  • UI互動:你可以用instrumentation直接向被測試Activity的UI發送擊鍵或者觸控時間。

Activity測試類別通過繼承TestCaseAssert類同樣支援JUnit架構。

兩個主要用來測試的子類是ActivityInstrumentationTestCase2ActivityUnitTestCase,如果需要測試一個Activity從非standard模式啟動,你可以使用SingleLaunchActivityTestCase

ActivityInstrumentationTestCase2

ActivityInstrumentationTestCase2 test case類使用正常的系統內容來對應用中一個或多個Activity做功能測試。它使用標準的系統Context,運行正常的被測試應用中的Activity。它允許你向被測試Activity發送類比的Intent,這樣你可以用它來測試可以處理多種類型Intent的Activity、期望接收Intent中特定類型資料的Activity或者兩種都有的Activity。注意:它並不支援類比的Context和Application,所以你無法將測試和正常系統隔離開。

ActivityUnitTestCase

ActivityUnitTestCase在隔離情況下測試一個單獨的Activity。在啟動Activity前,你必須注入一個類比的Context或者Application,或者兩個都有。你可以用它在隔離狀況下運行Activity測試,執行不與android互動的單元測試。你無法向被測試的Activity發送類比的Intent,但是你可以調用Activity.startActivity(Intent)然後查看收到的參數。

SingleLaunchActivityTestCase

SingleLaunchActivityTestCase類是用來方便在測試與測試之間不會改變的環境中對單個Activity進行測試的類,它只會調用setUp()tearDown()一次,而不是調用每個測試方法時都調用,它也不允許注入任何類比對象。

這個test case 類在測試一個Activity以非standard模式啟動時非常有用,它確保測試環境在測試與測試間沒有被重設,你可以用來測試Activity是否能夠正確地處理多次調用。

類比對象以及Activity測試

這裡包含關於如何使用android.test.mock包中的類比對象進行Activity測試的內容。

類比對象MockApplication只有在你用ActivityUnitTestCase
test case類進行Activity測試時才可以使用。預設情況下ActivityUnitTestCase建立一個隱藏的MockApplication對象作為測試的Application,你也可以用setApplication()注入自己的對象。

Activity測試斷言

ViewAsserts為view 定義斷言。你可以用它來檢驗view的對準和位置,也可以用來查看ViewGroup的狀態。

測試什麼
  • 輸入響應:測試Activity對在EditText中輸入資料後是否能夠準確響應。將擊鍵事件發送給Activity,然後用findViewById(int)來檢查VIew的狀態。你可以驗證發送一串合法的擊鍵事件時可以啟用“OK”按鈕,而輸入一串非法的擊鍵事件時“OK”按鈕不可用。你同樣可以測試Activity在接收到非法字元時在View中顯示錯誤資訊。
  • 生命週期事件:檢查你的應用中的每個Activity正確地處理生命週期事件。通常情況下,生命週期事件都是能觸發類似onCreate()或者onClick()等回調方法的action,它們來自於系統或者使用者。例如,一個Activity在收到pause或者destory事件時應該儲存現有狀態。記住螢幕方向的改變會導致當前Activity的destory,所以你應該測試裝置的轉動不會導致丟失應用的狀態。
  • Intent:測試每個Activity都能正確地處理在manifest檔案中intent filter中列出來的intent。你可以使用ActivityInstrumentationTestCase2發送類比的Intent給activity。
  • 運行時參數改變:測試每個Activity是否能夠正確處理在應用運行過程中可能發生的配置改變。這些包括螢幕方向的改變,當前語言的改變等,如何處理這些改變在Handling Runtime Changes中有說明。
  • 螢幕尺寸和解析度:在你發布應用前,確保你你在期望啟動並執行螢幕尺寸和大小上進行測試。你可以在多種螢幕尺寸和解析度的AVD上測試,或者你可以直接在目標機器上測試,更多資訊參見Supporting Multiple Screens。
下一步

要學習如何在eclipse中建立和運行測試,請參閱Testing from Eclipse with ADT,如果你沒有在使用eclipse,參見Testing from Other IDEs。

如果你需要手把手的測試教程,參見Activity Testing Tutorial。

附錄:UI測試注意事項

下面的內容是andorid應用UI測試中需要注意的事項,主要是協助你處理測試過程中在UI線程中執行的事件,觸控和擊鍵事件以及主畫面解鎖等。

在UI線程測試

應用中的Activity都在UI線程中執行,當UI執行個體化後,所有與UI的互動都必須在UI線程中執行。在正常啟動應用時,你就在操作UI線程,沒有什麼特別的。

當你對應用執行測試時就不太一樣,通過instrumentation-based的類,你可以調用被測試應用的操作UI的方法,其它的測試類別是不允許的。要在UI線程中執行一個完整的測試方法,你可以給線程加上註解@UIThreadTest,注意這樣方法的所有語句都會在UI線程中執行,不與UI互動的方法是不允許的,例如你不能調用Instrumentation.waitForIdleSync()

要在UI線程中執行測試方法的一部分,可以建立一個Runnable的匿名類,將你需要的語句放進run()方法中,然後執行個體化該類並作為參數傳入appActivity.runOnUiThread()方法,其中appActivity是你測試的應用的執行個體。

例如,下面的代碼執行個體化一個測試的Activity,為其中顯示的一個Spinner取得焦點,然後給它發送一個擊鍵事件,注意waitForIdleSyncsendKeys是不允許在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()中調用它。

解鎖模擬器或者裝置

在主畫面由於鎖屏設定進入鎖定狀態時UI測試是不起作用的,這是由於被測試應用收不到由sendKeys()發送過來的事件,最好的解決辦法是啟動你的模擬器或者裝置後禁用主畫面鎖屏。

你可以顯式地禁用螢幕鎖屏,需要在manifest檔案中添加一個許可權並且在被測試應用中關閉鎖屏,注意,你要麼在發布應用時刪除該代碼,要麼在發布的應用中用代碼關閉該功能。

在manifest檔案中添加<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>作為<manifest>標籤的子項目,在你要測試的Activity的onCreate()中添加下面的代碼來實現禁用鎖屏:

 mKeyGuardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);  mLock = mKeyGuardManager.newKeyguardLock("activity_classname");  mLock.disableKeyguard();

其中activity_classname是Activity的類名。

UI測試常見問題

下面列出在UI測試中經常會出現的失敗以及其原因:

WrongThreadException

問題:

失敗跟蹤資訊包含如下錯誤資訊:

android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

可能原因:

這個錯誤來源於你試圖從UI線程以外的線程發送UI事件給UI線程。通常發生於從測試包中發送UI事件但是沒有用@UIThread註解或者runOnUiThread()方法。

建議:

在UI線程中執行互動,使用提供instrumentation的測試類別。可以參見前面的Testing on the UI Thread。

java.lang.RuntimeException

問題:

失敗跟蹤資訊包含如下錯誤資訊:

java.lang.RuntimeException: This method can not be called from the main application thread 

可能原因:

這個錯誤通常是由於你的測試方法用@UiThreadTest註解,但是試圖做UI線程之外的事情或者調用runOnUiThread()

建議:

刪除@UiThreadTest註解,刪除runOnUiThread()方法,或者重構你的測試。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.