【问题标题】:NoMatchingRootException Espresso with custom ToastNoMatchingRootException 带有自定义 Toast 的浓缩咖啡
【发布时间】:2015-11-27 16:55:36
【问题描述】:

我从 Espresso 开始,我有一个自定义的 Toast,当用户输入错误时我会显示它(我知道我可以使用 EditText.setError(),但就是这样)。

这是 Toast 的代码

private static void showToast(Context context, String message, boolean isError) {
    if (context != null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        TextView toastView = (TextView) inflater.inflate(R.layout.error_toast_layout, null);
        if (!isError) {
            toastView.setBackgroundColor(context.getResources().getColor(R.color.alert_positive));
        }
        toastView.setText(message);
        Toast errorToast = new Toast(context);
        errorToast.setGravity(Gravity.TOP, 0, 0);
        errorToast.setDuration(Toast.LENGTH_SHORT);
        errorToast.setView(toastView);
        errorToast.show();
    }
}

我正在编写一个小的 UI 测试,它将断言当用户输入错误的输入时会显示正确的 Toast

这是测试

@RunWith(AndroidJUnit4.class)
@LargeTest
public class ForgotPasswordTest extends BaseEspressoTest<ForgotPasswordActivity> {

    @Test
    public void testEmailNotEntered() {
        onView(withId(R.id.email_et)).perform(typeText("w"), closeSoftKeyboard());
        onView(withId(R.id.btn_submit)).perform(click());
        onView(withText(R.string.incorrect_email_dialog)).inRoot(withDecorView(not(mActivityRule.getActivity().getWindow().getDecorView()))).check(matches(isDisplayed()));     
    }
}

如果我用我的自定义 Toast 代替常规 Toast,这可以正常工作,但是当我尝试使用我的 Toast 时会失败。我可以看到在测试期间正在显示 Toast。

这是错误:

android.support.test.espresso.NoMatchingRootException: Matcher 'with 装饰视图不 ' 与以下任何一项都不匹配 根源: [根{application-window-token=android.view.ViewRootImpl$W@2d629b84, window-token=android.view.ViewRootImpl$W@2d629b84, has-window-focus=true, 布局参数类型=1, layout-params-string=WM.LayoutParams{(0,0)(fillxfill) sim=#22 ty=1 fl=#8d810100 pfl=0x8 wanim=0x1030461 surfaceInsets=Rect(0, 0 - 0, 0)}, 装饰视图字符串=装饰视图{id=-1,可见性=可见,宽度=1080, 高度=1920,有焦点=真,有焦点=真, 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}}]

我还尝试根据 Toast 应该聚焦的事实来匹配它:

onView(withText(R.string.incorrect_email_dialog))
    .inRoot(isFocusable()).check(matches(isDisplayed()));

但这只是说它在视图层次结构中找不到它:

在层次结构中找不到匹配的视图:来自资源 id 的字符串: [incorrect_email_dialog] 值:请输入有效的电子邮件

【问题讨论】:

    标签: android testing android-espresso


    【解决方案1】:

    您可以尝试使用下面给出的 CustomToastMatcher:

    import android.os.IBinder;
    import android.support.test.espresso.Root;
    import android.view.WindowManager;
    import org.hamcrest.Description;
    import org.hamcrest.TypeSafeMatcher;
    
        public class ToastMatcher extends TypeSafeMatcher<Root> {
    
            @Override    public void describeTo(Description description) {
                description.appendText("is toast");
            }
    
            @Override    public boolean matchesSafely(Root root) {
                int type = root.getWindowLayoutParams().get().type;
                if ((type == WindowManager.LayoutParams.TYPE_TOAST)) {
                    IBinder windowToken = root.getDecorView().getWindowToken();
                    IBinder appToken = root.getDecorView().getApplicationWindowToken();
                    if (windowToken == appToken) {
                      //means this window isn't contained by any other windows. 
                    }
                }
                return false;
            }
        }
    

    在这样的测试用例中使用它:

    onView(withText(R.string.mssage)).inRoot(new ToastMatcher())
        .check(matches(isDisplayed()));
    

    其他参考: https://stackoverflow.com/a/33387980/2069407http://baroqueworksdev.blogspot.de/2015/03/how-to-check-toast-window-on-android.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-05
      • 1970-01-01
      • 2015-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-23
      相关资源
      最近更新 更多