Thursday 28 January 2016

How to Test Toast Message using Espresso?



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 - 
 

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 :-)

10 comments:

  1. 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.

    ReplyDelete
  2. I was able to verify the toast for successful login my app directly with

    onView(allOf(withId(R.string.login_successful), isDisplayed()));

    ReplyDelete
    Replies
    1. This is successful no matter what string message is in the withId, this is not a valid solution.

      Delete
  3. I am getting following error when i try above solution -
    "android.support.test.espresso.NoMatchingRootException: Matcher 'is toast' did not match any of the following roots "

    ReplyDelete
    Replies
    1. Hi, try with the change given below-

      if (windowToken == appToken) {
      return true;
      }

      Delete
  4. Thanks for your reply. I already did that based on above comment given by Max and i still see the same error.

    ReplyDelete
  5. Thanks I was getting the same error as Pavan, but managed to fix that by changing false to true

    ReplyDelete
  6. this does not work even if you put true

    ReplyDelete
  7. Try with below solution

    onView(withId(android.R.id.message))
    .inRoot(withDecorView(not(is(mRule.getActivity().getWindow().getDecorView()))))
    .check(matches(withText("Some message")));

    ReplyDelete
  8. This worked first time for me. Thank you very much!

    ReplyDelete