Andrew
Andrew

Reputation: 38029

Android testing. How to change text of a TextView using Espresso

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

Upvotes: 10

Views: 9080

Answers (4)

iCantC
iCantC

Reputation: 3190

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

Upvotes: 2

Sugandh Kumar
Sugandh Kumar

Reputation: 9

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()));
}

Upvotes: 0

amirul
amirul

Reputation: 430

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();
    }

Upvotes: 0

Be_Negative
Be_Negative

Reputation: 4972

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";
                }
            };
    }

Upvotes: 24

Related Questions