2016-05-09 1 views
0

У меня есть служба, которая подключается к серверу Socket.IO. Это простое приложение, которое отправляет сообщение, и оно возвращается к клиенту. У меня есть тест следующим образом:Espresso ждет текстового просмотра

@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 секунд, чтобы узнать, появилось ли сообщение. Как я могу это сделать?

ответ

4

Я решил ее, написав собственный IdlingResource, который проверяет вид на утверждение каждые isIdleNow и в конце концов, как раз в коде ниже:

@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; 
    } 
} 

Это работает, но, безусловно, есть лучший способ? Это чувствует себя супер хаки и что-то, что должен предоставить мне эспрессо. Тот факт, что это не приводит меня к мысли, что я не ошибаюсь в этом тесте. Есть ли лучший способ проверить одно и то же поведение?

+0

Благодарим вас за сообщение. Я изменил его для своих нужд! Этот ожидает, что число дочерних элементов линейного макета будет больше нуля. Дети добавляются динамически, и нам нужно убедиться, что хотя бы один есть! https://gist.github.com/Emeritus-DarranKelinske/3ed580732dc36cebdb7bc9059e4a5efe – dazza5000

+0

@Neo Ware, почему вы называете Espresso.unregisterIdlingResources (бездельник); сразу после регистрации? это не отменяет его сразу? – j2emanue

 Смежные вопросы

  • Нет связанных вопросов^_^