Home » Android » Android testing. Espresso. Change text in a TextView

Android testing. Espresso. Change text in a TextView

Posted by: admin June 15, 2020 Leave a comment

Questions:

It is easy to update an EditText with Espresso, but I can not find a way to change a text (like with a TextView.setText(“someText”); method) during the testing process.

 ViewAction.replaceText(stringToBeSet);

Is not working, cos it should be an EditText;

How to&Answers:

You can look into implementing your own ViewAction.

Here is the modified version of the replaceText viewaction from espresso library that is meant to work on the TextView.

 public static ViewAction setTextInTextView(final String value){
            return new ViewAction() {
                @SuppressWarnings("unchecked")
                @Override
                public Matcher<View> getConstraints() {
                    return allOf(isDisplayed(), isAssignableFrom(TextView.class));
                }

                @Override
                public void perform(UiController uiController, View view) {
                    ((TextView) view).setText(value);
                }

                @Override
                public String getDescription() {
                    return "replace text";
                }
            };
    }

Answer:

You can simply add your layout TextView in your layout that you have declared

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
        <TextView
            android:textColor="#123456"
            android:textSize="20dp"
            android:id="@+id/editText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

Write code in your test

@RunWith(AndroidJUnit4.class)
public class MainActivityTest {

    @Rule
    public ActivityTestRule<MainActivity> mMain = new ActivityTestRule<> (MainActivity.class);

   /*set text view in textView */

            public static ViewAction setTextInTextView(final String value){
                return new ViewAction() {
                    @SuppressWarnings("unchecked")
                    @Override
                    public Matcher<View> getConstraints() {
                        return allOf(isDisplayed(), isAssignableFrom(TextView.class));
        //                                        
        // To check that the found view is TextView or it's subclass like EditText
        // so it will work for TextView and it's descendants
                    }

                    @Override
                    public void perform(UiController uiController, View view) {
                        ((TextView) view).setText(value);
                    }

                    @Override
                    public String getDescription() {
                        return "replace text";
                    }
                };
            }

Now your method like that

          //need add your test case here
            @Test
            public void showTextView(){

                delay(2000);
                onView(withId(R.id.editText))
                        .perform(setTextInTextView("my text"));
                delay(2000);
            }

**Now you can also add delay method to show also emulator or real device*

    /* delay checking of this position */
    private void delay(long i) {

    try {
        Thread.sleep(i);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

Answer:

You can simply add your layout TextView in your layout that you have declared

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <TextView
        android:textColor="#123456"
        android:textSize="20dp"
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

** Write code in test class to check text is displaying on textview**

 @Test
public void checkUserId(){
    Espresso.onView(withId(R.id.textView)).check(ViewAssertions.matches(ViewMatchers.isDisplayed()));
}

Answer:

Kotlin version of the @Be_Negative awesome answer,

Since there is no default ViewAction for setting text on TextView in Espresso, you have to create your own.

Step 1: Define a new ViewAction to set text on TextView such as,

fun setTextInTextView(value: String): ViewAction {
    return object : ViewAction {
        override fun getConstraints(): Matcher<View> {
            return CoreMatchers.allOf(ViewMatchers.isDisplayed(), ViewMatchers.isAssignableFrom(TextView::class.java))
        }

        override fun perform(uiController: UiController, view: View) {
            (view as TextView).text = value
        }

        override fun getDescription(): String {
            return "replace text"
        }
    }
}

And then use it as,

onView(withId(R.id.my_text_view)).perform(setTextInTextView("Espresso is awesome"))