在Espresso Android中使用IdlingResource的正确方法

时间:2015-08-14 14:35:00

标签: android automated-tests android-espresso

我正在用Espresso编写UI测试。应用程序与服务器紧密配合,因此在很多情况下,我需要等待计算任一值,或者获取并显示数据等.Espresso建议使用IdlingResource。 我的IdlingResource类看起来像这样(简单明了的例子)。

public class IRViewVisible implements IdlingResource {

private View view;
private ResourceCallback callback;

public IRViewVisible(View view) {
    this.view = view;
}

@Override
public String getName() {
    return IRViewVisible.class.getName();
}

@Override
public boolean isIdleNow() {
    if(view.getVisibility() == View.VISIBLE && callback != null) {
        callback.onTransitionToIdle();
        return true;
    }
    return false;
}

@Override
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
    this.callback = resourceCallback;
}
}

如果我在任何地方都错了,请纠正我(因为在我看来,我的IdlingResources无法正常工作)。 我在setUp()注册了空闲资源,如下所示:

IRViewVisible ir = new IRViewVisible(View v);
Espresso.registerIdlingResources(ir).

在tearDown()上取消注册。

我找到了this article(有一个名为“注册一个绑定到Activity实例的组件”的部分) - 我没有使用他的模式,但我检查了注册后设置为IdlingResource的视图的哈希码(在每个方法),它不是相同的视图 - 所有哈希都是不同的。

另一个问题:一个Test类(它的结果)对另一个Test类没有任何影响,可以吗?

3 个答案:

答案 0 :(得分:2)

我猜你的问题源于getName()为IRViewVisible的所有实例返回相同的名称。这意味着您一次只能有一个已注册的实例 - 任何后续注册都将失败(无声!)。

您提到在每次测试结束时清除IdlingResources,但如果您一次注册多个实例,则需要确保每个实例都有唯一的名称。如果您在单个测试中注册了多个IRViewVisible 实例,那么您的问题就不清楚了。

关于你的最后一个问题:是的,这是可能的。 Android并没有在测试运行之间完全关闭应用程序 - 只是活动。可能导致问题的常见问题:

  • 未能清除持久状态(已保存的数据)。
  • 未能清除全局状态 - 例如静态变量/单例
  • 不等待后台线程完成运行。

顺便说一句,值得注意的是,您只能在onTransitionToIdle()内拨打isIdleNow()。这很有效(感谢@Be_Negative的抬头!)但它可能会大大减慢你的测试速度,因为Espresso每隔几秒钟只会轮询isIdleNow()。如果您在视图显示后立即致电onTransitionToIdle(),则应该会大大加快速度。

我需要类似于你自己的IRViewVisible,here's my effort

答案 1 :(得分:1)

因此,如果不设置对idlingResource的回调,则isIdleNow()方法永远不会返回true? 我认为最好像这样重构它:

@Override
public boolean isIdleNow() {
    boolean idle = view.getVisibility() == View.VISIBLE;
    if(idle && callback != null) {
        callback.onTransitionToIdle();
    }
    return idle;
} 

答案 2 :(得分:-2)

首先,您不需要使用Espresso IdlingResource来测试服务器调用。如果您在服务器呼叫中使用AsyncTask,Espresso将能够知道何时空闲,何时无空闲。如果这还不够:尝试以这种方式重构代码:

  IRViewVisible idlingResource = new IRViewVisible(yourView);
  IdlingPolicies.setMasterPolicyTimeout(waitingTime * 2, TimeUnit.MILLISECONDS);
        IdlingPolicies.setIdlingResourceTimeout(waitingTime * 2, TimeUnit.MILLISECONDS);

        // Now we wait
        Espresso.registerIdlingResources(idlingResource);

        // Stop and verify


        // Clean up
        Espresso.unregisterIdlingResources(idlingResource);

希望有所帮助。