问题 如果没有按钮,Espresso不会记录任何意图


我正在尝试编写一个测试来验证使用espresso启动意图,问题是目标()没有记录任何意图。

我有这个测试

  @Test
public void shoulddosomething(){
    startActivity();
    intended(hasComponent(hasClassName(TemplatePictureCaptureActivity.class.getName())));

}

在我的活动中,我有这个代码

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(onRequestLayout());
    Intent intent = new Intent(this, TemplatePictureCaptureActivity.class);
    startActivity(intent);
}

测试结果是这样的。

android.support.test.espresso.base.DefaultFailureHandler$AssertionFailedWithCauseError: Wanted to match 1 intents. Actually matched 0 intents.

IntentMatcher: has component: has component with: class name: is "cat.helm.recertel.ui.templatepicturecapture.TemplatePictureCaptureActivity" package name: an instance of java.lang.String short class name: an instance of java.lang.String

Matched intents:[]

Recorded intents:[]

我试图在onClickListen中启动intent并且它有效,但没有它我无法让它工作。我也试着闲置资源而没有运气。你知道怎么做到这一点吗?


4564
2018-04-11 09:09


起源

尝试在预期之前稍等一下(hasComponent(hasClassName(TemplatePictureCaptureActivity.class.getName()))); - ozo
它工作谢谢。但这不是一个糟糕的代码味道吗? - Borja
我不这么认为。我猜测视图还没有准备好测试意图,android仍在设置视图(setContentView(onRequestLayout())),这就是为什么它无法找到意图。如果单击按钮,则在设置视图后单击。 - ozo
然后我将评论作为您接受的答案。 - ozo


答案:


解决方案是注册一个空闲资源以等待第二个活动。

在我的情况下,测试将保持如下:

  @Test
public void shoulddosomething() {
    startActivity();
    String templatePictureActivityClassName = TemplatePictureCaptureActivity.class.getName();
    Espresso.registerIdlingResources(new WaitActivityIsResumedIdlingResource(templatePictureActivityClassName));
    intended(hasComponent(hasClassName(templatePictureActivityClassName)));
}

而这里是闲置的资源。

 private static class WaitActivityIsResumedIdlingResource implements IdlingResource {
    private final ActivityLifecycleMonitor instance;
    private final String activityToWaitClassName;
    private volatile ResourceCallback resourceCallback;
    boolean resumed = false;
    public WaitActivityIsResumedIdlingResource(String activityToWaitClassName) {
        instance = ActivityLifecycleMonitorRegistry.getInstance();
        this.activityToWaitClassName = activityToWaitClassName;
    }

    @Override
    public String getName() {
        return this.getClass().getName();
    }

    @Override
    public boolean isIdleNow() {
        resumed = isActivityLaunched();
        if(resumed && resourceCallback != null) {
            resourceCallback.onTransitionToIdle();
        }

        return resumed;
    }

    private boolean isActivityLaunched() {
        Collection<Activity> activitiesInStage = instance.getActivitiesInStage(Stage.RESUMED);
        for (Activity activity : activitiesInStage) {
            if(activity.getClass().getName().equals(activityToWaitClassName)){
               return true;
            }
        }
        return false;
    }

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

11
2018-04-14 14:44



您可以考虑在测试后取消注册空闲资源。 - iamreptar
但是,如果您只有一个Activity可以使用不同的数据一次又一次地启动,那么这不一定有效。 - scriptocalypse


试着等一会儿

intended(hasComponent(hasClassName(TemplatePictureCaptureActivity.class.getName(‌​))));

2
2018-04-12 15:50



我已经做了进一步的调查,你的解决方案并不总是有效,这取决于测试失败与否的给定时间量,这个数量可能会改变。我找到了一个合适的解决方案。 - Borja