浓咖啡等待textview [英] Espresso waiting for textview
问题描述
我有一个正在连接到Socket.IO服务器的服务.这是一个简单的应用程序,它发送一条消息,并将其回显给客户端.我的测试如下:
I have a service that is connecting to a Socket.IO server. It is a simple app that sends a message and it gets echoed back to the client. I have a test as follows:
@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秒钟,然后检查其中是否包含文本.
I have the server running on my local network, and in this scenario everything runs and passes. However, if I add a 3 second delay in the server, then the test fails. I want to basically say wait for up to X seconds and then check if it contains the text.
我看到有人回答使用IdlingResource时也遇到了类似的问题.但是我不确定如何将其集成到我的应用程序中.我想我必须实现isIdleNow函数.我正在使用连接到com.koushikdutta.async.http.socketio.SocketIOClient的服务;
I have seen similar questions with people answering to use an IdlingResource. However I am not sure how to integrate this into my app. I guess I have to implement the isIdleNow function. I am using a service that connects to com.koushikdutta.async.http.socketio.SocketIOClient;
它永远不会闲置,它只是坐在那里监听套接字.因此,我并不是真正地在等待完成某件事,我只想继续检查视图长达X秒钟,以查看是否有消息到达.我该怎么办?
It doesn't ever go idle though, it just sits there listening on the socket. So I am not really waiting for something to finish, I just want to keep checking the view for up to X seconds to see if a message arrived. How might I do this?
推荐答案
我已通过编写自定义IdlingResource来解决此问题,该方法检查每个isIdleNow上的视图断言,并最终按照以下代码超时:
I have solved it by writing a custom IdlingResource that checks the view assertion on every isIdleNow and eventually times out as per the code below:
@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;
}
}
它有效,但是肯定有更好的方法吗?这感觉超级骇人,Espresso应该为我提供一些东西.事实并非如此,这使我相信我对这种测试的想法是错误的.有没有更好的方法来测试相同的行为?
It works but surely there is a better way? This feels super hacky and something Espresso should provide me. The fact that it doesn't leads me to believe I am thinking the wrong way about this test. Is there a better way to test the same behaviour?
这篇关于浓咖啡等待textview的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!