Espresso声称不需要Thread.sleep()
,但是我的代码不能工作,除非我包含它。我正在连接一个IP,在连接时,会显示一个进度对话框。我需要一个Thread.sleep()
调用来等待对话框解除。这是我的测试代码,我在其中使用它:
IP.enterIP(); // fills out an IP dialog (this is done with espresso)
//progress dialog is now shown
Thread.sleep(1500);
onView(withId(R.id.button).perform(click());
我在没有调用Thread.sleep()
的情况下尝试过这段代码,但它显示R.id.Button
不存在。我能让它工作的唯一方法是使用Thread.sleep()
调用。
另外,我也尝试过用像getInstrumentation().waitForIdleSync()
这样的东西来代替Thread.sleep()
,但是仍然没有成功。
这是唯一的方法吗?还是我错过了什么?
提前谢谢。
发布于 2014-03-21 23:45:42
在我看来,正确的方法是:
/** Perform action of waiting for a specific view id. */
public static ViewAction waitId(final int viewId, final long millis) {
return new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isRoot();
}
@Override
public String getDescription() {
return "wait for a specific view with id <" + viewId + "> during " + millis + " millis.";
}
@Override
public void perform(final UiController uiController, final View view) {
uiController.loopMainThreadUntilIdle();
final long startTime = System.currentTimeMillis();
final long endTime = startTime + millis;
final Matcher<View> viewMatcher = withId(viewId);
do {
for (View child : TreeIterables.breadthFirstViewTraversal(view)) {
// found view with required ID
if (viewMatcher.matches(child)) {
return;
}
}
uiController.loopMainThreadForAtLeast(50);
}
while (System.currentTimeMillis() < endTime);
// timeout happens
throw new PerformException.Builder()
.withActionDescription(this.getDescription())
.withViewDescription(HumanReadables.describe(view))
.withCause(new TimeoutException())
.build();
}
};
}
然后使用模式将是:
// wait during 15 seconds for a view
onView(isRoot()).perform(waitId(R.id.dialogEditor, TimeUnit.SECONDS.toMillis(15)));
发布于 2016-03-11 02:56:43
感谢AlexK的精彩回答。在某些情况下,您需要在代码中进行一些延迟。它不一定在等待服务器响应,但可能在等待动画完成。我个人对Espresso idolingResources有问题(我认为我们为了一个简单的事情写了很多行代码),所以我把AlexK做的方式改成了下面的代码:
/**
* Perform action of waiting for a specific time.
*/
public static ViewAction waitFor(final long millis) {
return new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isRoot();
}
@Override
public String getDescription() {
return "Wait for " + millis + " milliseconds.";
}
@Override
public void perform(UiController uiController, final View view) {
uiController.loopMainThreadForAtLeast(millis);
}
};
}
因此,您可以创建一个Delay
类并将此方法放入其中,以便轻松地访问它。您可以以同样的方式在测试类中使用它:onView(isRoot()).perform(waitFor(5000));
发布于 2015-07-21 00:08:04
在寻找类似问题的答案时,我偶然发现了这个线程,当时我正在等待服务器响应,并根据响应更改元素的可见性。
虽然上面的解决方案绝对有帮助,但我最终找到了this excellent example from chiuki,现在每当我在应用程序空闲期间等待操作发生时,我都会使用这种方法。
我已经将ElapsedTimeIdlingResource()添加到我自己的实用程序类中,现在可以有效地使用它作为Espresso合适的替代方案,现在的用法很好很干净:
// Make sure Espresso does not time out
IdlingPolicies.setMasterPolicyTimeout(waitingTime * 2, TimeUnit.MILLISECONDS);
IdlingPolicies.setIdlingResourceTimeout(waitingTime * 2, TimeUnit.MILLISECONDS);
// Now we wait
IdlingResource idlingResource = new ElapsedTimeIdlingResource(waitingTime);
Espresso.registerIdlingResources(idlingResource);
// Stop and verify
onView(withId(R.id.toggle_button))
.check(matches(withText(R.string.stop)))
.perform(click());
onView(withId(R.id.result))
.check(matches(withText(success ? R.string.success: R.string.failure)));
// Clean up
Espresso.unregisterIdlingResources(idlingResource);
https://stackoverflow.com/questions/21417954
复制相似问题