浓缩咖啡测试失败,进度对话框未从顶部删除
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”?我不知道布局是什么样的,但有时这会有所帮助。以上是关于浓缩咖啡测试失败,进度对话框未从顶部删除的主要内容,如果未能解决你的问题,请参考以下文章