Now a days many apps uses Toast Messages and if you are testing android app which displays Toast Messages and you want to write Espresso test case to assert the Toast Message then this post will help you to achieve that. In last post I have shared how to add Custom Matcher? which will help you to understand this post clearly as I am going to add a custom Matcher to test Toast.
Video Tutorial -
Video Tutorial -
Check below is the ToastMatcher which identifies the Toast is not part of activity window-
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) { return true; } } return false; }
This ToastMatcher you can use it in your test case like this -
1. Test if the Toast Message is Displayed
onView(withText(R.string.mssage)).inRoot(new ToastMatcher()) .check(matches(isDisplayed()));
2. Test if the Toast Message is not Displayed
onView(withText(R.string.mssage)).inRoot(new ToastMatcher()) .check(matches(not(isDisplayed())));
3. Test id the Toast contains specific Text Message
onView(withText(R.string.mssage)).inRoot(new ToastMatcher()) .check(matches(withText("Invalid Name"));
I hope this post helps you find your code coverage for your test suit :)
Please Share your feedback in comments section below and follow QA Automated to get latest post update.Happy Testing :-)
Thank you for your post! It was very helpful to me but you need to return true if windowToken == appToken is true in the matchesSafely method.
ReplyDeleteI was able to verify the toast for successful login my app directly with
ReplyDeleteonView(allOf(withId(R.string.login_successful), isDisplayed()));
This is successful no matter what string message is in the withId, this is not a valid solution.
DeleteI am getting following error when i try above solution -
ReplyDelete"android.support.test.espresso.NoMatchingRootException: Matcher 'is toast' did not match any of the following roots "
Hi, try with the change given below-
Deleteif (windowToken == appToken) {
return true;
}
Thanks for your reply. I already did that based on above comment given by Max and i still see the same error.
ReplyDeleteThanks I was getting the same error as Pavan, but managed to fix that by changing false to true
ReplyDeletethis does not work even if you put true
ReplyDeleteTry with below solution
ReplyDeleteonView(withId(android.R.id.message))
.inRoot(withDecorView(not(is(mRule.getActivity().getWindow().getDecorView()))))
.check(matches(withText("Some message")));
This worked first time for me. Thank you very much!
ReplyDelete