【发布时间】: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: [Root{application-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=DecorView{id=-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}}, Root{application-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=DecorView{id=-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}}, Root{application-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=DecorView{id=-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 版本上工作得很好
标签: android coded-ui-tests android-testing android-espresso ui-testing