在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();
- 什么是ActionBar菜单项中的orderInCategory以及为什么它被用于..?
- 将位图转换为文件
- 在Android中使用新的“manifestmerger”属性
- 如何在Android中创build滚动轮播页面?
- 无法获取urlhttps://dl-ssl.google.com/android/repository/addons_list-1.xml,原因:连接到https://dl-ssl.google.com拒绝
- 缩放图像以填充ImageView宽度并保持宽高比
- Google语音识别超时
- Widget.AppCompat.Button colorButtonNormal显示灰色
- Android的Facebook 4.0 SDK如何获得电子邮件,出生date和用户的性别