我正在为我的应用程序编写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))));
}
片段显示progressDialog
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
查看层次结构: +&gt; DecorView {id = -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,child-count = 1} | + - &gt; LinearLayout {id = -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,child-count = 2} | + - &gt; ViewStub {id = 16909149,visibility = GONE,width = 0,height = 0,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 = true,is-selected = false,root-is-layout-requested = false,has-input-connection = false,x = 0.0,y = 0.0} | + - &gt; FrameLayout {id = 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 -connection = false,x = 0.0,y = 38.0,child-count = 1} | + ---&gt; RelativeLayout {id = -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,child-count = 1} | + ----&gt; LinearLayout {id = -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,child-count = 2} | + -----&gt; CustomProgressIndicator {id = 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, has-input-connection = false,x = 183.0,y = 0.0,child-count = 2} | + ------&gt; ImageView {id = 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 ,has-input-connection = false,x = 0.0,y = 0.0} | + ------&gt; ImageView {id = 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 ,has-input-connection = false,x = 0.0,y = 0.0} | + -----&gt; TextView {id = 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, has-input-connection = false,x = 175.0,y = 138.0,text = Loading,input-type = 0,ime-target = false,has-links = false} | at dalvik.system.VMStack.getThreadStackTrace(Native Method) 在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) at tk.swapnilUtilities.eRecommendationAndroid.ui.ScrHomeNewTest.testRecommendationCountIOException(ScrHomeNewTest.java:59) at 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)
[编辑] 我已禁用动画,但结果仍然相同。我使用模拟模式来模拟收到的响应。立即返回模拟错误响应。手动运行应用程序后,我发现在我的应用程序发送到后台之前,不会删除进度对话框。
有人能指出我如何修复此错误?
答案 0 :(得分:0)
至少有几件事可能会发生。
“为避免剥落,我们强烈建议您关闭系统 用于测试的虚拟或物理设备上的动画。
在您的设备上,在“设置” - >“开发者选项”下,禁用 以下3种设置:窗口动画比例过渡动画 比例动画师持续时间表“
https://google.github.io/android-testing-support-library/docs/espresso/setup/
“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资源的示例。有一些部分,所以我建议看看节省一些时间。如果没别的话,至少要查看源代码。