2015-08-21 104 views
9

我有使用postDelayed呼叫活動:這將運行在應用程序啓動咖啡和postDelayed

public class SplashActivity extends Activity { 
    private Handler handler = new Handler(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(...); 
     handler.postDelayed(new Runnable() { 
      public void run() { finish(); } 
     }, 3000L); 
    } 
} 

,我需要導航它和我的登錄屏幕。但是,UIController的loopMainThreadUntilIdle似乎並未將處理程序中的基礎MessageQueue考慮在內。因此,此行爲在隊列中仍有消息時立即結束。

onView(withId(R.id.splash_screen)).perform(new ViewAction() { 
    @Override 
    public Matcher<View> getConstraints() { 
     return isAssignableFrom(View.class); 
    } 

    @Override 
    public String getDescription() { 
     return ""; 
    } 

    @Override 
    public void perform(final UiController uiController, final View view) { 
     uiController.loopMainThreadUntilIdle(); 
    } 
}); 

我一直無法弄清楚如何阻塞,直到隊列耗盡。 Android本身阻止我做了很多我想嘗試的事情(比如擴展Handler和覆蓋postDelayed方法等等)。

任何人都有關於如何處理postDelayed的建議?

我寧願避免uiController.loopMainThreadForAtLeast,這似乎哈克(像了Thread.sleep會)

回答

8

當咖啡等待,它實際上確實需要帳戶MessageQueue,但是從你覺得有什麼不同的方式。要成爲空閒,隊列必須爲空,的任務要從現在的起超過15毫秒運行。

您可以自己檢查代碼,特別是方法loopUntil()UiControllerImpl.java和文件QueueInterrogator.java。在後面的文件中,您還可以找到Espresso如何檢查MessageQueue(方法determineQueueState())的邏輯。

現在,如何解決你的問題?方法有很多種:

  1. 使用AsyncTask代替Handler,睡在後臺線程來執行動作onPostExecute()。這樣做是因爲Espresso將等待AsyncTask完成,但您可能不喜歡另一個線程的開銷。

  2. 睡在你的測試代碼中,但你不喜歡那種方法。

  3. 編寫您的自定義IdlingResource:這是一個通用的機制,讓Espresso知道什麼時候空閒,以便它可以運行動作和斷言。對於這種方法,你可以:

    • 使用自帶的咖啡

    • 呼叫increment()CountingIdlingResource當您發佈可運行和decrement()可運行裏面的邏輯已經運行

    • 後註冊您的IdlingResource在測試設置和取消註冊它在拆除

參見:docs and sampleanother sample

+1

我想我可能只是抽出消息推入隊列,並注入一些其他實現作爲IdlingResource。我將在我的代碼中有一個默認實現,它遵循處理程序,在測試代碼中有一個是IdlingResource和icnrements/decrements – Matt

0

據我所知,沒有等到活動結束方法咖啡。你可以實現你自己的waitForCondition版本,機器人已經有了。這樣您只需等待需要的時間,您就可以檢測到活動未完成的問題。

你基本上每x毫秒輪詢你的情況,類似。

while (!conditionIsMet() && currentTime < timeOut){ 
    sleep(100); 
} 

boolean conditionIsMet() { 
    return "espresso check for if your splash view exists"; 
} 
+0

的問題是,Android提供你沒有辦法真正窺視消息隊列,看看是否有任何正在排隊。它必須是在啓動時被攔截並取代的東西(我認爲這是robotium的做法)。 – Matt

+0

waitForCondition類只是輪詢你自己寫的條件。至於檢查隊列的機器人,我不這麼認爲,我也看到過類似機器人的問題。 – JohanShogun

+0

對於這個用例,您應該能夠等待發生的操作,而不是查看消息隊列(從測試立場來看這真的更有趣)。 – JohanShogun