how to get text from textview using espresso

25,067

Solution 1

The basic idea is to use a method with an internal ViewAction that retrieves the text in its perform method. Anonymous classes can only access final fields, so we cannot just let it set a local variable of getText(), but instead an array of String is used to get the string out of the ViewAction.

    String getText(final Matcher<View> matcher) {
        final String[] stringHolder = { null };
        onView(matcher).perform(new ViewAction() {
            @Override
            public Matcher<View> getConstraints() {
                return isAssignableFrom(TextView.class);
            }
    
            @Override
            public String getDescription() {
                return "getting text from a TextView";
            }
    
            @Override
            public void perform(UiController uiController, View view) {
                TextView tv = (TextView)view; //Save, because of check in getConstraints()
                stringHolder[0] = tv.getText().toString();
            }
        });
        return stringHolder[0];
    }

Note: This kind of view data retrievers should be used with care. If you are constantly finding yourself writing this kind of methods, there is a good chance, you're doing something wrong from the get go. Also don't ever access the View outside of a ViewAssertion or ViewAction, because only there it is made sure, that interaction is safe, as it is run from UI thread, and before execution it is checked, that no other interactions meddle.

Solution 2

If you want to check text value with another text, you can create Matcher. You can see my code to create your own method:

 public static Matcher<View> checkConversion(final float value){
    return new TypeSafeMatcher<View>() {

        @Override
        protected boolean matchesSafely(View item) {
            if(!(item instanceof TextView)) return false;

            float convertedValue = Float.valueOf(((TextView) item).getText().toString());
            float delta = Math.abs(convertedValue - value);

            return delta < 0.005f;
        }

        @Override
        public void describeTo(Description description) {
            description.appendText("Value expected is wrong");
        }
    };
}
Share:
25,067

Related videos on Youtube

Nick Dong
Author by

Nick Dong

Updated on October 01, 2020

Comments

  • Nick Dong
    Nick Dong over 3 years

    I want get text string shown in a textview in LinearLayout. can espresso do that? If not, is there other way to do that or can I use android api in espresso test case? I am using API 17 18 or newer, espresso 1.1(It should be the latest one.). I have no clue about this. Thanks.

    • haffax
      haffax about 10 years
      Yes, Espresso can do this, if in a hacky way. But most of the time you shouldn't have to, because in tests you usually want to compare text in a textview with a given text or test some property of it. With more details on what you are actually trying to do in your test, it is easier to give a helpful answer.
    • Nick Dong
      Nick Dong about 10 years
      Well, what actually the hacky way is? How to do that? I need to get these text to insert to a report. Thanks for your consideration, @haffax
    • Adam Burley
      Adam Burley over 3 years
      @haffax for example, your app may call a web service which has unpredictable results. you want to check some text to determine what logic to perform, as the expected behaviour depends on the response the app got from the web service. this kind of thing can't be solved with just an assertion, you need to get text, then run your logic to determine the expectation, and only then you can do assertions.
  • Loebre
    Loebre over 7 years
    Could you please put an example usage of your code? I don't see how to use your solution. Thank you
  • CROSP
    CROSP about 7 years
    @Loebre you can use it like this getText(withId(viewId));
  • Rakib
    Rakib over 5 years
    @haffax But what if you are checking if a list of strings are sorted in the front-end? Then getText is dearly needed. Should there be not an implementation like Selenum getText()?
  • haffax
    haffax over 5 years
    @MohammadRakibAmin Don't know your specific case, but in general: A fixed scenario will solve this without having this kind of logic in place. E.g. if your test db returns the fruits "strawberries, apples, bananas" then confirming that the first shown fruit is apple, the next is banana and the last is strawberry is the strongest test for the scenario. Just testing that whatever is been showing is in alphabetic order is not of much value and can lead to false negatives.
  • Adam Burley
    Adam Burley over 3 years
    this only helps if you want to do an assertion against the returned value, not when you want to just get the value without doing an assertion against it. for example, your app may call a web service which has unpredictable results. you want to check some text to determine what logic to perform, as the expected behaviour depends on the response the app got from the web service. this kind of thing can't be solved with just an assertion, you need to get text, then run your logic to determine the expectation, and only then you can do assertions.
  • emaleavil
    emaleavil over 3 years
    You can read in my answer that I am referring to check (assert). I think that if you want to get the value the best answer is using the most voted answer.