2016-05-09 11 views
0

私はSocket.IOサーバに接続しているサービスを持っています。それはメッセージを送信し、それがクライアントにエコーバックされる単純なアプリです。エスプレッソ待ちテキストビュー

@Test 
public void checkSendMessage() { 

    final String testMessage = "Here is a test message"; 

    onView(withId(R.id.textEntry)).perform(typeText(testMessage), closeSoftKeyboard()); 
    onView(withId(R.id.send)).perform(click()); 
    onView(withId(R.id.messages)).check(matches(withText(containsString(testMessage)))); 
} 

私は、サーバーが私のローカルネットワーク上で実行されているが、このシナリオのすべてが実行され、渡され、次のように私は、テストを持っています。しかし、サーバーに3秒の遅延を追加すると、テストは失敗します。私は基本的にX秒間待ってからテキストが含まれているかどうかを確認したいと思っています。

私は、IdlingResourceを使用する人に似た質問をしました。しかし、私はどのように私のアプリにこれを統合するか分からない。私はisIdleNow関数を実装する必要があると思います。私はcom.koushikdutta.async.http.socketio.SocketIOClientに接続するサービスを使用しています。

まだアイドル状態にはなりませんが、ソケットに接続しているだけです。だから私は本当に何かが終了するのを待っているわけではない、私はちょうどメッセージが到着したかどうかを見るためにX秒までのビューをチェックし続けたい。どうすればいい?

@Test 
public void checkSendMessage() { 

    final String testMessage = "Here is a test message"; 

    onView(withId(R.id.textEntry)).perform(typeText(testMessage), closeSoftKeyboard()); 
    onView(withId(R.id.send)).perform(click()); 

    waitFor(onView(withId(R.id.messages)), matches(withText(containsString(testMessage))), 5000); 
} 

private void waitFor(ViewInteraction viewInteraction, ViewAssertion viewAssertion, long timeout) { 

    PollingTimeoutIdler idler = new PollingTimeoutIdler(viewInteraction, viewAssertion, timeout); 
    Espresso.registerIdlingResources(idler); 

    viewInteraction.check(viewAssertion); 

    Espresso.unregisterIdlingResources(idler); 
} 

private class PollingTimeoutIdler implements IdlingResource { 

    private final ViewAssertion mViewAssertion; 
    private final long mTimeout; 
    private final long mStartTime; 
    private ResourceCallback mCallback; 
    private volatile View mTestView; 

    public PollingTimeoutIdler(ViewInteraction viewInteraction, ViewAssertion viewAssertion, long timeout) { 
     mViewAssertion = viewAssertion; 
     mTimeout = timeout; 
     mStartTime = System.currentTimeMillis(); 

     viewInteraction.check(new ViewAssertion() { 
      @Override 
      public void check(View view, NoMatchingViewException noViewFoundException) { 
       mTestView = view; 
      } 
     }); 
    } 

    @Override 
    public String getName() { 
     return getClass().getSimpleName(); 
    } 

    @Override 
    public boolean isIdleNow() { 

     long elapsed = System.currentTimeMillis() - mStartTime; 
     boolean timedOut = elapsed >= mTimeout; 

     boolean idle = testView() || timedOut; 
     if(idle) { 
      mCallback.onTransitionToIdle(); 
     } 

     return idle; 
    } 

    private boolean testView() { 

     if(mTestView != null) { 
      try { 
       mViewAssertion.check(mTestView, null); 
       return true; 
      } 
      catch(AssertionFailedError ex) { 
       return false; 
      } 
     } 
     else { 
      return false; 
     } 
    } 

    @Override 
    public void registerIdleTransitionCallback(ResourceCallback callback) { 
     mCallback = callback; 
    } 
} 

それは動作しますが、確かに良い方法があります:

答えて

4

私は以下のコードごとのように外にすべてのisIdleNow、最終的には倍のビューアサーションをチェックするカスタムIdlingResourceを書き込むことによってそれを解決していますか?これはスーパーハッキーとエスプレッソが私に提供すべき何かを感じる。私がこの試験について間違った考え方をしていると私が信じさせないという事実。同じ動作をテストするより良い方法はありますか?

+0

ありがとうございます。私のニーズに合わせて修正しました!これは、線形レイアウトの子の数がゼロより大きくなるのを待ちます。子供たちは動的に追加され、少なくとも1人はそこにいることを確認する必要があります! https://gist.github.com/Emeritus-DarranKelinske/3ed580732dc36cebdb7bc9059e4a5efe – dazza5000

+0

@Neo WareなぜあなたはEspresso.unregisterIdlingResources(idler)を呼び出しますか?登録直後ですか?すぐに登録を解除しないのですか? – j2emanue