Dmi*_* K. 4 java testing android qa android-espresso
我是 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;
}
}
Run Code Online (Sandbox Code Playgroud)
我是这么称呼它的:
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);
Run Code Online (Sandbox Code Playgroud)
如何在不阻塞主线程的情况下延迟测试执行?
所以我有一个闪屏片段,它在延迟后处理到我正在测试的片段。@Aarons 回答有效。
onView(isRoot()).perform(waitFor(5000))
Run Code Online (Sandbox Code Playgroud)
科特林等待():
fun waitFor(delay: Long): ViewAction? {
return object : ViewAction {
override fun getConstraints(): Matcher<View> = isRoot()
override fun getDescription(): String = "wait for $delay milliseconds"
override fun perform(uiController: UiController, v: View?) {
uiController.loopMainThreadForAtLeast(delay)
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您只想等待一段时间,则实际上并不需要 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);
}
};
}
Run Code Online (Sandbox Code Playgroud)
并使用它:
onView(withId(R.id.row_content)).check(matches(isDisplayed())).perform(click());
onView(isRoot()).perform(waitFor(5000);
Run Code Online (Sandbox Code Playgroud)
但是,如果您知道视图将在一段时间后出现,那么您可以使用 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();
}
}
Run Code Online (Sandbox Code Playgroud)
并使用它例如:
onView(withId(R.id.row_content)).check(matches(isDisplayed())).perform(click());
onView(withId(R.id.main_content)).perform(waitUntil(isDisplayed()))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5029 次 |
最近记录: |