检测棉花糖中的吐司
Posted
技术标签:
【中文标题】检测棉花糖中的吐司【英文标题】:Detecting toasts in Marshmallow 【发布时间】:2016-01-28 10:31:17 【问题描述】:我正在用 espresso 编写一些 ui 测试,并且正在尝试断言 toast 消息。我遇到的问题是我的代码在 Lollipop 上工作,但在棉花糖上失败,我不明白为什么。
我的代码基本上是打开一个对话框、填写一封电子邮件并单击一个按钮。这应该会带来一个 toast 并且确实如此(我通过设备上的目视检查确认)但我的测试未能检测到 toast。
为此,我为 toast 创建了一个自定义匹配器类:
import android.os.IBinder;
import android.support.test.espresso.Root;
import android.view.WindowManager;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import static com.google.android.exoplayer.util.Assertions.checkArgument;
import static com.google.android.exoplayer.util.Assertions.checkNotNull;
import static org.hamcrest.CoreMatchers.equalTo;
public class ToastMatcher
public static Matcher<Root> withToastText(String toastText)
// use preconditions to fail fast when a test is creating an invalid matcher.
checkArgument(!(toastText.equals(null)));
return withToastText(equalTo(toastText));
public static Matcher<Root> withToastText(final Matcher<String> matcherText)
// use preconditions to fail fast when a test is creating an invalid matcher.
checkNotNull(matcherText);
return new TypeSafeMatcher<Root>()
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)
// windowToken == appToken means this window isn't contained by any other windows.
// if it was a window for an activity, it would have TYPE_BASE_APPLICATION.
return true;
return false;
;
至于我的测试用例
@Test
public void success()
String successMessage = mActivityRule.getActivity().getResources().getString(R.string.info_recover_instructions);
String ok = mActivityRule.getActivity().getResources().getString(android.R.string.ok);
// Click forgot button
onView(withId(R.id.lg_forgot)).perform(click());
// Fill email
onView(withClassName(endsWith("EditText"))).perform(typeText(USERNAME));
// Click OK button
onView(withText(ok))
.check(matches(isEnabled()))
.perform(click());
// Assert Toast
onView(withText(successMessage)).inRoot(ToastMatcher.withToastText(successMessage)).check(matches(isDisplayed()));
正如我之前所说,这在 Lollipop 上运行得很好,但在 Marshmallow 上它给了我以下错误:
android.support.test.espresso.NoMatchingRootException: Matcher 'is toast' did not match any of the following roots: [Rootapplication-window-token=android.view.ViewRootImpl$W@a66b932, window-token=android.view.ViewRootImpl$W@a66b932, has-window-focus=true, layout-params-type=2, layout-params-string=WM.LayoutParams(0,0)(wrapxwrap) gr=#11 sim=#20 ty=2 fl=#1820002 fmt=-3 wanim=0x103045c needsMenuKey=2, decor-view-string=DecorViewid=-1, visibility=VISIBLE, width=1026, height=483, 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, Rootapplication-window-token=android.view.ViewRootImpl$W@8d64683, window-token=android.view.ViewRootImpl$W@8d64683, has-window-focus=false, layout-params-type=2, layout-params-string=WM.LayoutParams(0,0)(wrapxwrap) gr=#11 sim=#20 ty=2 fl=#1800002 fmt=-3 wanim=0x103045c needsMenuKey=2, decor-view-string=DecorViewid=-1, visibility=VISIBLE, width=1026, height=598, has-focus=true, has-focusable=true, has-window-focus=false, 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, Rootapplication-window-token=android.view.ViewRootImpl$W@90a2000, window-token=android.view.ViewRootImpl$W@90a2000, has-window-focus=false, layout-params-type=1, layout-params-string=WM.LayoutParams(0,0)(fillxfill) ty=1 fl=#81810100 wanim=0x103045b needsMenuKey=2, decor-view-string=DecorViewid=-1, visibility=VISIBLE, width=1080, height=1920, has-focus=true, has-focusable=true, has-window-focus=false, 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=3]
我做错了什么还是应该在 android Marshmallow 上做不同的事情?
【问题讨论】:
您是否尝试通过文字来敬酒? 是的。我尝试简单地做 onView(withText(successMessage)).check(matches(isDisplayed())) 但这也不起作用,所以我创建了自定义匹配器,它在除 MM 之外的其他 android 版本上工作得很好 【参考方案1】:试试这个。不确定它是否适用于棉花糖:
onView(withText(R.string.toastText))
.inRoot(withDecorView(not(is(mActivityRule.getActivity().getWindow().getDecorView()))))
.check(matches(isDisplayed()));
【讨论】:
嗨。我试过了,但它也没有检测到棉花糖上的吐司以上是关于检测棉花糖中的吐司的主要内容,如果未能解决你的问题,请参考以下文章
Android Studio getSlotFromBufferLocked:棉花糖中的未知缓冲区错误