我是Espresso测试框架的新手。现在,我有一个任务来测试一些可与异步后端一起使用的应用程序。在第一个活动开始时,某些片段仅在加载后出现。这可能需要几秒钟,所以最简单的方法是等待5到7秒钟。但是,使用IdlingResource会冻结主线程,因此直到等待超时结束后才能加载我的后端数据。
这就是我使用IdlingResource的方式:
public static class ElapsedTimeIdlingResource implements IdlingResource {
private final long startTime;
private final long waitingTime;
private ResourceCallback resourceCallback;
ElapsedTimeIdlingResource(long waitingTime) {
this.startTime = System.currentTimeMillis();
this.waitingTime = waitingTime;
}
@Override
public String getName() {
return ElapsedTimeIdlingResource.class.getName() + ":" + waitingTime;
}
@Override
public boolean isIdleNow() {
long elapsed = System.currentTimeMillis() - startTime;
boolean idle = (elapsed >= waitingTime);
if (idle) resourceCallback.onTransitionToIdle();
return idle;
}
@Override
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
this.resourceCallback = resourceCallback;
}
}
我怎么称呼它:
long waitingTime = 5000;
onView(withId(R.id.row_content)).check(matches(isDisplayed())).perform(click());
IdlingPolicies.setMasterPolicyTimeout(waitingTime * 2, TimeUnit.MILLISECONDS);
IdlingPolicies.setIdlingResourceTimeout(waitingTime * 2, TimeUnit.MILLISECONDS);
IdlingResource idlingResource = new ElapsedTimeIdlingResource(waitingTime);
IdlingRegistry.getInstance().register(idlingResource);
// .... do some tests
IdlingRegistry.getInstance().unregister(idlingResource);
如何在不阻塞主线程的情况下延迟测试执行?
答案 0 :(得分:0)
如果您只想等待一段时间,则实际上并不需要IdlingResource:
public static ViewAction waitFor(long delay) {
return new ViewAction() {
@Override public Matcher<View> getConstraints() {
return ViewMatchers.isRoot();
}
@Override public String getDescription() {
return "wait for " + delay + "milliseconds";
}
@Override public void perform(UiController uiController, View view) {
uiController.loopMainThreadForAtLeast(delay);
}
};
}
并使用它:
onView(withId(R.id.row_content)).check(matches(isDisplayed())).perform(click());
onView(isRoot()).perform(waitFor(5000);
但是,如果您知道该视图将在一段时间后出现,则可以使用IdlingResource例如:
public static ViewAction waitUntil(Matcher<View> matcher) {
return actionWithAssertions(new ViewAction() {
@Override public Matcher<View> getConstraints() {
return ViewMatchers.isAssignableFrom(View.class);
}
@Override public String getDescription() {
StringDescription description = new StringDescription();
matcher.describeTo(description);
return String.format("wait until: %s", description);
}
@Override public void perform(UiController uiController, View view) {
if (!matcher.matches(view)) {
LayoutChangeCallback callback = new LayoutChangeCallback(matcher);
try {
IdlingRegistry.getInstance().register(callback);
view.addOnLayoutChangeListener(callback);
uiController.loopMainThreadUntilIdle();
} finally {
view.removeOnLayoutChangeListener(callback);
IdlingRegistry.getInstance().unregister(callback);
}
}
}
});
}
private static class LayoutChangeCallback implements IdlingResource, View.OnLayoutChangeListener {
private Matcher<View> matcher;
private IdlingResource.ResourceCallback callback;
private boolean matched = false;
LayoutChangeCallback(Matcher<View> matcher) {
this.matcher = matcher;
}
@Override public String getName() {
return "Layout change callback";
}
@Override public boolean isIdleNow() {
return matched;
}
@Override public void registerIdleTransitionCallback(ResourceCallback callback) {
this.callback = callback;
}
@Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
matched = matcher.matches(v);
callback.onTransitionToIdle();
}
}
并以它为例:
onView(withId(R.id.row_content)).check(matches(isDisplayed())).perform(click());
onView(withId(R.id.main_content)).perform(waitUntil(isDisplayed()))
答案 1 :(得分:0)
因此,我有一个启动画面片段,经过延迟后,该片段会转换为我正在测试的片段。 @Aarons答案适用。
onView(isRoot()).perform(waitFor(5000))
Kotlin waitfor():
fun waitFor(delay: Long): ViewAction {
return object : ViewAction {
override fun perform(uiController: UiController?, view: View?) {
uiController?.loopMainThreadForAtLeast(delay)
}
override fun getConstraints(): Matcher<View> {
return isRoot()
}
override fun getDescription(): String {
return "wait for " + delay + "milliseconds"
}
}
}