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

4

10

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

Brownie answered 29/9, 2015 at 14:32 Comment(0)
P
24

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";
                }
            };
    }
Pelerine answered 29/9, 2015 at 17:26 Comment(1)
Works like a charm. I will like couple more your responses ))Brownie
M
2

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"))
Multinational answered 12/4, 2020 at 15:12 Comment(0)
N
0

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();
    }
Nottingham answered 6/11, 2018 at 21:12 Comment(0)
P
0

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()));
}
Plumbery answered 30/3, 2020 at 17:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.