Android 安卓浓缩咖啡触感测试

Android 安卓浓缩咖啡触感测试,android,android-espresso,Android,Android Espresso,我有: 按下登录按钮后,将显示一个加载对话框,异步任务将调用服务器检查凭据。在响应LoginActivity之后,我正在测试的名为finish()的witch和MainActivity被启动 按下登录按钮后,测试将挂起。 还使用: onView(withId(R.id.login_email_textview)).perform(clearText(), closeSoftKeyboard()); onView(withId(R.id.password_editt

我有:

按下登录按钮后,将显示一个加载对话框,异步任务将调用服务器检查凭据。在响应LoginActivity之后,我正在测试的名为finish()的witch和MainActivity被启动

按下登录按钮后,测试将挂起。 还使用:

        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)));
@规则
public IntentsTestRule mActivityRule=新IntentsTestRule(LoginActivity.class);
在我调用startActivity()之后的代码中,我也在LoginActivity上调用finish()

在登录按钮上,我正在呼叫截击请求。

如何解决您的问题 我假设
加载对话框
显示了一个动画的
进度条

同时使用
ProgressBar
Volley
实际上是个不错的主意。
ProgressBar
将强制
Espresso
等待
Volley
在后台完成其工作

我假设您的测试“挂起”,因为您没有关闭
加载对话框
。因此,要解决此问题,请在收到来自
Volley
的响应时关闭
LoadingDialog
。但不要使用
Espresso
关闭
加载对话框

更多信息 单独使用
ProgressBar
Volley
时存在“已知问题”:

ProgressBar的问题
如果
加载对话框
显示动画的
进度条
,则动画会阻止
浓缩咖啡
。动画使应用程序的主线程保持忙碌,并等待它超时

截击问题
Espresso
不知道
Volley
。如果
Volley
在后台线程中执行请求(我希望如此),
Espresso
不会等待,您的测试可能会在
Volley
返回响应之前结束


一个可以用来让浓缩咖啡等待任何事情。

所以这就是我想出的解决方案:

自定义IdlingResource:

@Rule
public IntentsTestRule<LoginActivity> mActivityRule = new IntentsTestRule<>(LoginActivity.class);

基于

使用sleep强制线程等待响应。它可以通过thread.sleep()工作,但不要认为这是最好的方法。我将实现自定义IdlingResource以等待截击请求完成。我使用iDingResource使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)));