我有一个连接到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秒,看看是否有消息到达。我怎么能这样做?
答案 0 :(得分:5)
我已经通过编写自定义IdlingResource来解决它,该自定义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;
}
}
它有效,但肯定有更好的方法吗?这感觉超级hacky和Espresso应该提供给我的东西。事实上,它并没有让我相信我正在考虑这个测试的错误方法。有没有更好的方法来测试相同的行为?