Android 文本视图中文本的浓缩咖啡不';不匹配所选视图

Android 文本视图中文本的浓缩咖啡不';不匹配所选视图,android,android-espresso,Android,Android Espresso,我在喝浓缩咖啡时遇到了一个奇怪的测试失败。下面是在显示的对话框中测试TextView。我得到以下错误: com.google.android.apps.common.testing.ui.espresso.base.DefaultFailureHandler$AssertionFailedWithCauseError: 'with string from resource id: <2131099772>' doesn't match the selected view. Ex

我在喝浓缩咖啡时遇到了一个奇怪的测试失败。下面是在显示的对话框中测试TextView。我得到以下错误:

   com.google.android.apps.common.testing.ui.espresso.base.DefaultFailureHandler$AssertionFailedWithCauseError: 'with string from resource id: <2131099772>' doesn't match the selected view.
Expected: with string from resource id: <2131099772>[my_content] value: Test Content Available
Got: "TextView{id=2131296340, res-name=dialog_content, visibility=VISIBLE, width=620, height=38, 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, text=Test Content Available, input-type=0, ime-target=false}"

at dalvik.system.VMStack.getThreadStackTrace(Native Method)
at java.lang.Thread.getStackTrace(Thread.java:579)
at com.google.android.apps.common.testing.ui.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:69)
at com.google.android.apps.common.testing.ui.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:40)
at com.google.android.apps.common.testing.ui.espresso.ViewInteraction.runSynchronouslyOnUiThread(ViewInteraction.java:159)
at com.google.android.apps.common.testing.ui.espresso.ViewInteraction.check(ViewInteraction.java:133)
at com.myapp.testContentDetails(FPATest.java:109)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
at com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner.onStart(GoogleInstrumentationTestRunner.java:167)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)
Caused by: junit.framework.AssertionFailedError: 'with string from resource id: <2131099772>' doesn't match the selected view.
Expected: with string from resource id: <2131099772>[my_content] value: Test Content Available
Got: "TextView{id=2131296340, res-name=dialog_content, visibility=VISIBLE, width=620, height=38, 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, text=Test Content Available, input-type=0, ime-target=false}"

at com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.assertThat(ViewMatchers.java:789)
at com.google.android.apps.common.testing.ui.espresso.assertion.ViewAssertions$2.check(ViewAssertions.java:76)
at com.google.android.apps.common.testing.ui.espresso.ViewInteraction$2.run(ViewInteraction.java:145)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5081)
at java.lang.reflect.Method.invokeNative(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:781)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
我也试着用下面的语句来做,但是得到了一个NoMatchingViewException,即使是通过异常的视图层次结构中的视图显示

onView(withText(R.string.my_content)).check(
                matches(isDisplayed()));

关于为什么会失败有什么帮助吗?值得注意的是,我能够在对话框的同级字段上显示withText()IsDisplay()

这个答案是根据@haffax上面的评论创建的

/**
 * Original source from Espresso library, modified to handle spanned fields
 * 
 * Returns a matcher that matches a descendant of {@link TextView} that is
 * displaying the string associated with the given resource id.
 * 
 * @param resourceId
 *            the string resource the text view is expected to hold.
 */
public static Matcher<View> withText(final int resourceId) {

    return new BoundedMatcher<View, TextView>(TextView.class) {
        private String resourceName = null;
        private String expectedText = null;

        @Override
        public void describeTo(Description description) {
            description.appendText("with string from resource id: ");
            description.appendValue(resourceId);
            if (null != this.resourceName) {
                description.appendText("[");
                description.appendText(this.resourceName);
                description.appendText("]");
            }
            if (null != this.expectedText) {
                description.appendText(" value: ");
                description.appendText(this.expectedText);
            }
        }

        @Override
        public boolean matchesSafely(TextView textView) {
            if (null == this.expectedText) {
                try {
                    this.expectedText = textView.getResources().getString(
                            resourceId);
                    this.resourceName = textView.getResources()
                            .getResourceEntryName(resourceId);
                } catch (Resources.NotFoundException ignored) {
                    /*
                     * view could be from a context unaware of the resource
                     * id.
                     */
                }
            }
            if (null != this.expectedText) {
                return this.expectedText.equals(textView.getText()
                        .toString());
            } else {
                return false;
            }
        }
    };
}
/**
*来自Espresso library的原始源代码,已修改为处理跨字段
* 
*返回匹配{@link TextView}的子代的匹配器,该子代是
*显示与给定资源id关联的字符串。
* 
*@param resourceId
*文本视图应包含的字符串资源。
*/
带文本的公共静态匹配器(最终int-resourceId){
返回新的BoundedMatcher(TextView.class){
私有字符串resourceName=null;
私有字符串expectedText=null;
@凌驾
公共无效说明(说明){
description.appendText(“带有来自资源id的字符串:”);
description.appendValue(resourceId);
if(null!=此.resourceName){
说明.附录文本(“[”);
description.appendText(this.resourceName);
说明.附录文本(“]”);
}
if(null!=this.expectedText){
description.appendText(“值:”);
description.appendText(this.expectedText);
}
}
@凌驾
公共布尔匹配安全(TextView TextView){
if(null==this.expectedText){
试一试{
this.expectedText=textView.getResources().getString(
资源ID);
this.resourceName=textView.getResources()
.getResourceEntryName(资源ID);
}捕获(已忽略Resources.NotFoundException){
/*
*视图可以来自不知道资源的上下文
*身份证。
*/
}
}
if(null!=this.expectedText){
返回此.expectedText.equals(textView.getText()
.toString());
}否则{
返回false;
}
}
};
}

Espresso附带的内置withText(int resourceId)有问题。仅当检查的文本是java.lang.String时,它才起作用,但使用的许多文本是CharSequence的其他子类,如Editable或Spanable。确保您正在使用的文本类型实际上是字符串,如果不是,请编写自己的匹配器,在不查看类型的情况下匹配字符串内容。@haffax-Perfect!我在TextView中使用Html.fromHtml()设置了文本,这当然会产生一个跨对象。编写了一个自定义匹配器,它只在#matchessesafely()中的textView.getText()上执行了一个#toString(),它工作得非常好。如果你想将此作为答案提交,我会将其标记为已接受,谢谢!在我的例子中,我匹配了屏幕上的所有caps文本。使用allCaps属性集时,真正的字符串是小写的,所以我必须匹配小写。
/**
 * Original source from Espresso library, modified to handle spanned fields
 * 
 * Returns a matcher that matches a descendant of {@link TextView} that is
 * displaying the string associated with the given resource id.
 * 
 * @param resourceId
 *            the string resource the text view is expected to hold.
 */
public static Matcher<View> withText(final int resourceId) {

    return new BoundedMatcher<View, TextView>(TextView.class) {
        private String resourceName = null;
        private String expectedText = null;

        @Override
        public void describeTo(Description description) {
            description.appendText("with string from resource id: ");
            description.appendValue(resourceId);
            if (null != this.resourceName) {
                description.appendText("[");
                description.appendText(this.resourceName);
                description.appendText("]");
            }
            if (null != this.expectedText) {
                description.appendText(" value: ");
                description.appendText(this.expectedText);
            }
        }

        @Override
        public boolean matchesSafely(TextView textView) {
            if (null == this.expectedText) {
                try {
                    this.expectedText = textView.getResources().getString(
                            resourceId);
                    this.resourceName = textView.getResources()
                            .getResourceEntryName(resourceId);
                } catch (Resources.NotFoundException ignored) {
                    /*
                     * view could be from a context unaware of the resource
                     * id.
                     */
                }
            }
            if (null != this.expectedText) {
                return this.expectedText.equals(textView.getText()
                        .toString());
            } else {
                return false;
            }
        }
    };
}