Android Espresso 启动活动测试
Android Espresso startActivity testing
我有:
onView(withId(R.id.login_email_textview)).perform(clearText(), closeSoftKeyboard());
onView(withId(R.id.password_edittext)).perform(clearText(), closeSoftKeyboard());
onView(withId(R.id.login_email_textview)).perform(typeText(email), closeSoftKeyboard());
onView(withId(R.id.password_edittext)).perform(typeText(password), closeSoftKeyboard());
onView(withId(R.id.email_sign_in_button)).perform(click());
intended(hasComponent(new ComponentName(getTargetContext(), MainActivity.class)));
按下登录按钮后,会出现加载对话框,异步任务会调用服务器来检查凭据。响应 LoginActivity 后, 我正在测试调用 finish() 并启动 MainActivity。
按下登录按钮后测试挂起。
同时使用:
@Rule
public IntentsTestRule<LoginActivity> mActivityRule = new IntentsTestRule<>(LoginActivity.class);
同样在我的代码中 I/m 调用 startActivity() 之后,我在 LoginActivity 上调用 finish()。
在 sign_in_button 我正在呼叫 Volley 请求。
如何解决您的问题
我假设 LoadingDialog
正在显示动画 ProgressBar
。
同时使用 ProgressBar
和 Volley
实际上是个不错的主意。 ProgressBar
将强制 Espresso
等待,直到 Volley
在后台完成其工作。
我假设,你的测试 "hang" 因为你没有关闭 LoadingDialog
。因此,要解决此问题,请在收到 Volley
的响应时关闭 LoadingDialog
。但是不要使用 Espresso
来关闭 LoadingDialog
.
更多信息
单独使用ProgressBar
和Volley
时有"known issues":
ProgressBar
的问题
如果 LoadingDialog
显示动画 ProgressBar
,则动画块 Espresso
。动画使应用程序的主线程保持忙碌,Espresso
一直等到超时。
See here for workarounds
Volley
的问题
Espresso
不知道 Volley
。如果 Volley
在后台线程中执行请求(我希望如此),Espresso
不会等待,您的测试可能会在 Volley
returns 响应之前结束。
一个IdlingResource
可以用来让Espresso
等待任何事情。
这就是我想出的解决方案:
自定义空闲资源:
public class VolleyIdlingResource implements IdlingResource {
private static final String TAG = "VolleyIdlingResource";
private final String resourceName;
// written from main thread, read from any thread.
private volatile ResourceCallback resourceCallback;
private Field requests;
private RequestQueue requestQueue;
public VolleyIdlingResource(String resourceName, Context context) throws SecurityException, NoSuchFieldException {
this.resourceName = checkNotNull(resourceName);
requestQueue = MyApplication.get(context).getRequestQueue();
requests = RequestQueue.class.getDeclaredField("requests");
requests.setAccessible(true);
}
@Override
public String getName() {
return resourceName;
}
@Override
public boolean isIdleNow() {
try {
Set<Request> set = (Set<Request>) requests.get(requestQueue);
int count = set.size();
if (set != null) {
if (count == 0) {
resourceCallback.onTransitionToIdle();
} else {
}
return count == 0;
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
@Override
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
this.resourceCallback = resourceCallback;
}
}
然后在测试中:
VolleyIdlingResource volleyResources;
try {
volleyResources = new VolleyIdlingResource("VolleyCalls", mActivityRule.getActivity());
registerIdlingResources(volleyResources);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
intended(hasComponent(new ComponentName(getTargetContext(), MainActivity.class)));
我有:
onView(withId(R.id.login_email_textview)).perform(clearText(), closeSoftKeyboard());
onView(withId(R.id.password_edittext)).perform(clearText(), closeSoftKeyboard());
onView(withId(R.id.login_email_textview)).perform(typeText(email), closeSoftKeyboard());
onView(withId(R.id.password_edittext)).perform(typeText(password), closeSoftKeyboard());
onView(withId(R.id.email_sign_in_button)).perform(click());
intended(hasComponent(new ComponentName(getTargetContext(), MainActivity.class)));
按下登录按钮后,会出现加载对话框,异步任务会调用服务器来检查凭据。响应 LoginActivity 后, 我正在测试调用 finish() 并启动 MainActivity。
按下登录按钮后测试挂起。 同时使用:
@Rule
public IntentsTestRule<LoginActivity> mActivityRule = new IntentsTestRule<>(LoginActivity.class);
同样在我的代码中 I/m 调用 startActivity() 之后,我在 LoginActivity 上调用 finish()。
在 sign_in_button 我正在呼叫 Volley 请求。
如何解决您的问题
我假设 LoadingDialog
正在显示动画 ProgressBar
。
同时使用 ProgressBar
和 Volley
实际上是个不错的主意。 ProgressBar
将强制 Espresso
等待,直到 Volley
在后台完成其工作。
我假设,你的测试 "hang" 因为你没有关闭 LoadingDialog
。因此,要解决此问题,请在收到 Volley
的响应时关闭 LoadingDialog
。但是不要使用 Espresso
来关闭 LoadingDialog
.
更多信息
单独使用ProgressBar
和Volley
时有"known issues":
ProgressBar
的问题
如果 LoadingDialog
显示动画 ProgressBar
,则动画块 Espresso
。动画使应用程序的主线程保持忙碌,Espresso
一直等到超时。
See here for workarounds
Volley
的问题
Espresso
不知道 Volley
。如果 Volley
在后台线程中执行请求(我希望如此),Espresso
不会等待,您的测试可能会在 Volley
returns 响应之前结束。
一个IdlingResource
可以用来让Espresso
等待任何事情。
这就是我想出的解决方案:
自定义空闲资源:
public class VolleyIdlingResource implements IdlingResource {
private static final String TAG = "VolleyIdlingResource";
private final String resourceName;
// written from main thread, read from any thread.
private volatile ResourceCallback resourceCallback;
private Field requests;
private RequestQueue requestQueue;
public VolleyIdlingResource(String resourceName, Context context) throws SecurityException, NoSuchFieldException {
this.resourceName = checkNotNull(resourceName);
requestQueue = MyApplication.get(context).getRequestQueue();
requests = RequestQueue.class.getDeclaredField("requests");
requests.setAccessible(true);
}
@Override
public String getName() {
return resourceName;
}
@Override
public boolean isIdleNow() {
try {
Set<Request> set = (Set<Request>) requests.get(requestQueue);
int count = set.size();
if (set != null) {
if (count == 0) {
resourceCallback.onTransitionToIdle();
} else {
}
return count == 0;
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
@Override
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
this.resourceCallback = resourceCallback;
}
}
然后在测试中:
VolleyIdlingResource volleyResources;
try {
volleyResources = new VolleyIdlingResource("VolleyCalls", mActivityRule.getActivity());
registerIdlingResources(volleyResources);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
intended(hasComponent(new ComponentName(getTargetContext(), MainActivity.class)));