在android espresso中检查toast消息

谁会知道如何testing在Android的咖啡吐司消息的外观? 在机器人中,它使用起来很简单,但是开始使用浓缩咖啡,但没有得到确切的命令。

这个稍长的声明适合我:

import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.matcher.RootMatchers.withDecorView; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.withText; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; .... onView(withText(R.string.TOAST_STRING)).inRoot(withDecorView(not(is(getActivity().getWindow().getDecorView())))).check(matches(isDisplayed())); 

被接受的答案是一个很好的答案,但没有为我工作。 所以我search了一下,发现了这篇博客文章 。 这给了我一个如何做的想法,我更新了上面的解决scheme。

首先我实施了ToastMatcher:

 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) { // 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; } } 

然后我实现了像这样的检查方法:

 public void isToastMessageDisplayed(int textId) { onView(withText(textId)).inRoot(MobileViewMatchers.isToast()).check(matches(isDisplayed())); } 

MobileViewMatchers是访问匹配器的容器。 在那里我定义了静态方法isToast()

 public static Matcher<Root> isToast() { return new ToastMatcher(); } 

这对我来说就像一个魅力。

首先确保导入:

 import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.matcher.ViewMatchers.withText; import static android.support.test.espresso.matcher.RootMatchers.withDecorView; import static android.support.test.espresso.assertion.ViewAssertions.matches; 

在你的class级里,你可能有这样一个规则:

 @Rule public ActivityTestRule<MyNameActivity> activityTestRule = new ActivityTestRule<>(MyNameActivity.class); 

在你的testing里面:

 MyNameActivity activity = activityTestRule.getActivity(); onView(withText(R.string.toast_text)). inRoot(withDecorView(not(is(activity.getWindow().getDecorView())))). check(matches(isDisplayed())); 

这工作对我来说,它很容易使用。

首先创build一个我们可以在我们的testing用例中使用的Toast Matcher –

 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; } 

1.testingToast消息是否显示

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

2.testingToast消息是否不显示

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

3.testingID Toast包含特定的文本消息

 onView(withText(R.string.mssage)).inRoot(new ToastMatcher()) .check(matches(withText("Invalid Name")); 

谢谢,Anuja

注意 – 这个答案是来自这个POST。

Toast被实现的方式使得可以检测已经显示的Toast。 然而,没有办法通过调用show()来查看Toast是否被请求,或者在show()和toast变得可见之间的时间段之间阻塞。 这是打开无法解决的时间问题(你只能通过睡眠和希望解决)。

如果你真的想要validation这一点,那么使用Mockito和一个testing间谍是一个不太好的select:

 public interface Toaster { public void showToast(Toast t); private static class RealToaster { @Override public void showToast(Toast t) { t.show(); } public static Toaster makeToaster() { return new RealToaster(); } } Then in your test public void testMyThing() { Toaster spyToaster = Mockito.spy(Toaster.makeToaster()); getActivity().setToaster(spyToaster); onView(withId(R.button)).perform(click()); getInstrumentation().runOnMainSync(new Runnable() { @Override public void run() { // must do this on the main thread because the matcher will be interrogating a view... Mockito.verify(spyToaster).showToast(allOf(withDuration(Toast.LENGTH_SHORT), withView(withText("hello world")); }); } // create a matcher that calls getDuration() on the toast object Matcher<Toast> withDuration(int) // create a matcher that calls getView() and applies the given view matcher Matcher<Toast> withView(Matcher<View> viewMatcher) another answer regarding this if(someToast == null) someToast = Toast.makeText(this, "sdfdsf", Toast.LENGTH_LONG); boolean isShown = someToast.getView().isShown();