浓缩咖啡测试失败,进度对话框未从顶部删除

Posted

技术标签:

【中文标题】浓缩咖啡测试失败,进度对话框未从顶部删除【英文标题】:Espresso test failing with progress dialog not removed from top 【发布时间】:2017-07-25 07:45:52 【问题描述】:

我正在为我的应用编写 Espresso 测试。当我运行它时,我的一项测试失败了,当它被调试时它工作正常。这似乎是一个线程问题。调用 api 时,代码首先显示 ProgressDialog,当收到响应时将其删除。测试失败表示运行此测试时仍显示进度对话框。

测试是:

@Rule
    public IntentsTestRule<ScrDoctorHomeNew> activityTestRule = new IntentsTestRule<>(ScrDoctorHomeNew.class,false,false);

@Test
    public void testRecommendationCountIOException() 
        ApiFactory.INSTANCE.setErrorObservable(Observable.error(new IOException("Network Error")));

        activityTestRule.launchActivity(null);

        onView(withId(R.id.lblOldRecommandation)).check(matches(withText(String.format(activityTestRule.getActivity().getString(R.string.txt_doctor_old_recommandation), 0))));
    

显示进度对话框的片段

private void fetchProfileData() 
        if (mActivity != null) 
            mActivity.showProgressDialogInUiThread(mActivity.getResources().getString(R.string.str_loading));
        
        ApiFactory.INSTANCE.getDocProfileRetriever().getProfile(LocalDataManager.getInstance().getUser().getUserId()).subscribe(
                new Subscriber<ProfileMessage>() 
                    @Override
                    public void onCompleted() 
                        if (mActivity != null) 
                            mActivity.dismissProgressDialogInUiThread();
                        
                    

                    @Override
                    public void onError(Throwable e) 
                        if (mActivity != null) 
                            mActivity.dismissProgressDialogInUiThread();
                        
                        updateRecommendationCount(0);
                        Log.e(HomeFragment.class.getSimpleName(),"Exception:",e);
                    

                    @Override
                    public void onNext(ProfileMessage profileMessage) 
                        if (profileMessage != null) 
                            ArrayList<String> list = profileMessage.getProblemRecommendations();
                            if (list != null) 
                                updateRecommendationCount(list.size());
                             else 
                                updateRecommendationCount(0);
                            
                         else 
                            updateRecommendationCount(0);
                        
                    
                );
    

BaseActivity 显示进度对话框

public void showProgressDialogInUiThread(String text) 
        mProgressDlgFragment =
                ProgressDialogFragment.getInstance(false, false, text,
                        R.style.ProgressDialogStyle);
        mProgressDlgFragment.show(getSupportFragmentManager(), ProgressDialogFragment.DIALOG_TAG);

    

    public void dismissProgressDialogInUiThread() 
        if (mProgressDlgFragment != null) 
            mProgressDlgFragment.dismiss();
        
    

显示的错误是:

android.support.test.espresso.NoMatchingViewException:在层次结构中找不到匹配的视图:id:tk.swapnilUtilities.eRecommendationAndroid:id/lblOldRecommandation

查看层次结构: +>DecorViewid=-1, visibility=VISIBLE, width=480, height=854, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled =true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0 , y=0.0, 子数=1 | +->LinearLayoutid=-1, visibility=VISIBLE, width=480, height=854, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-已启用=true,is-focused=false,is-focusable=false,is-layout-requested=false,is-selected=false,root-is-layout-requested=false,has-input-connection=false,x= 0.0, y=0.0, 子数=2 | +-->ViewStubid=16909149, visibility=GONE, width=0, height=0, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-启用=真,聚焦=假,可聚焦=假,布局请求=真,被选择=假,根是布局请求=假,输入连接=假,x = 0.0, y=0.0 | +-->FrameLayoutid=16908290, res-name=content, visibility=VISIBLE, width=480, height=816, has-focus=false, has-focusable=false, has-window-focus=true, is- clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-连接=假,x=0.0,y=38.0,子计数=1 | +--->RelativeLayoutid=-1, visibility=VISIBLE, width=480, height=816, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, 子数=1 | +---->LinearLayoutid=-1, visibility=VISIBLE, width=480, height=187, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false , is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false , x=0.0, y=314.0, 孩子数=2 | +----->CustomProgressIndicatorid=2131558672, res-name=progress_indicator, visibility=VISIBLE, width=114, height=114, has-focus=false, has-focusable=false, has-window-focus=true , is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, 有-输入连接=假,x=183.0,y=0.0,子计数=2 | +-------->ImageViewid=2131558674, res-name=progress_indicator_view_inner, visibility=VISIBLE, width=114, height=114, has-focus=false, has-focusable=false, has-window-focus= true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false,有输入连接=假,x=0.0,y=0.0 | +------>ImageViewid=2131558675, res-name=progress_indicator_view_outer, visibility=VISIBLE, width=114, height=114, has-focus=false, has-focusable=false, has-window-focus= true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false,有输入连接=假,x=0.0,y=0.0 | +----->TextViewid=2131558673, res-name=tv_message, visibility=VISIBLE, width=129, height=49, has-focus=false, has-focusable=false, has-window-focus=true , is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, 有-input-connection=false, x=175.0, y=138.0, text=Loading, input-type=0, ime-target=false, has-links=false | 在 dalvik.system.VMStack.getThreadStackTrace(本机方法) 在 java.lang.Thread.getStackTrace(Thread.java:579) 在 android.support.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:92) 在 android.support.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:56) 在 android.support.test.espresso.ViewInteraction.runSynchronouslyOnUiThread(ViewInteraction.java:184) 在 android.support.test.espresso.ViewInteraction.check(ViewInteraction.java:158) 在 tk.swapnilUtilities.eRecommendationAndroid.ui.ScrHomeNewTest.testRecommendationCountIOException(ScrHomeNewTest.java:59) 在 java.lang.reflect.Method.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke(Method.java:525) 在 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 在 org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 在 org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 在 org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 在 android.support.test.internal.statement.UiThreadStatement.evaluate(UiThreadStatement.java:55) 在 android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:270) 在 org.junit.rules.RunRules.evaluate(RunRules.java:20) 在 org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 在 org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 在 org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 在 org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 在 org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 在 org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 在 org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 在 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 在 org.junit.runners.ParentRunner.run(ParentRunner.java:363) 在 org.junit.runners.Suite.runChild(Suite.java:128) 在 org.junit.runners.Suite.runChild(Suite.java:27) 在 org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 在 org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 在 org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 在 org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 在 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 在 org.junit.runners.ParentRunner.run(ParentRunner.java:363) 在 org.junit.runner.JUnitCore.run(JUnitCore.java:137) 在 org.junit.runner.JUnitCore.run(JUnitCore.java:115) 在 android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59) 在 android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262) 在 android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1667)

[编辑]我已禁用动画,但结果仍然相同。我正在使用模拟模式来模拟收到的响应。立即返回模拟错误响应。手动运行应用程序后,我观察到在我的应用程序被发送到后台之前,进度对话框不会被删除。

谁能指出我该如何解决这个错误?

【问题讨论】:

【参考方案1】:

至少有几件事可能。

    确保在运行测试之前禁用动画。您可能已经这样做了,但不清楚,值得向其他读者指出。

“为避免片状,我们强烈建议您关闭系统 用于测试的虚拟或物理设备上的动画。

在您的设备上,在“设置”->“开发者选项”下禁用 以下3个设置: 窗口动画比例 过渡动画 scale Animator 持续时间比例"

https://google.github.io/android-testing-support-library/docs/espresso/setup/


    另一件事(很可能是问题所在)是测试在收到响应之前完成。如果进度条仍然存在,这是有道理的。解决方案是使用 Espresso IdlingResource。

“Espresso 的核心是其无缝同步的能力 正在测试的应用程序的所有测试操作。默认, Espresso 等待当前消息队列中的 UI 事件 处理并让默认 AsyncTasks 在继续之前完成 下一个测试操作。

但是,在某些情况下,应用程序执行后台 通过非标准的操作(例如与 Web 服务通信) 方法;例如:直接创建和管理线程。

在这种情况下,您必须使用空闲资源通知 Espresso 应用程序的长期运行。”

https://google.github.io/android-testing-support-library/docs/espresso/idling-resource/index.html


如果文档不够清晰 - 或者,请查看代码实验室 https://codelabs.developers.google.com/codelabs/android-testing

有几个示例说明如何使用 Idling 资源。它有几部分,所以我建议您看一下以节省一些时间。如果没有别的,至少看看源代码。

【讨论】:

我已禁用动画,但结果仍然相同。我正在使用模拟模式来模拟收到的响应。立即返回模拟错误响应。 您是否尝试过在 withId 部分之前使用“descendentOf”?我不知道布局是什么样的,但有时这会有所帮助。

以上是关于浓缩咖啡测试失败,进度对话框未从顶部删除的主要内容,如果未能解决你的问题,请参考以下文章

如何让浓缩咖啡测试在特定条件下失败

手机睡着的浓缩咖啡测试

带有“hasBackground”的浓缩咖啡测试

勺子和浓缩咖啡测试

是否可以截屏并用浓缩咖啡测试像素值?

指纹读取器浓缩咖啡测试