Why android espresso test fails when checking whether textView text ends with expected string (when ellipsized)

Issue

I have an android test checking that external text message is truncated and ends with three dots when applying android:ellipsize”end”. I do not know why test fails despite text presented in a activity is properly formatted.

enter image description here

@Test
fun when_errorMessage_is_very_long_then_text_of_errorMessageTextView_ends_with_dots() {

    //given
    val errorMessage  """
            Very long error, Very long error, Very long error, Very long error, Very long error,
            Very long error, Very long error, Very long error, Very long error, Very long error,
            Very long error, Very long error, Very long error, Very long error, Very long error,
            Very long error, Very long error, Very long error, Very long error, Very long 
    error,"""

    //when
    presentErrorActivityWith(errorMessage)

    //then
    onView(withId(R.id.errorMessageTextView)).check(matches(withText(endsWith("..."))));
}

screenshot of ErrorActivity

I use functionality imported from

import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4

errorMessageTextView declaration in ErrorActivity layout

<TextView
    android:id"@+id/errorMessageTextView"
    android:layout_width"wrap_content"
    android:layout_height"wrap_content"

    android:ellipsize"end"
    android:maxLines"2"

    android:paddingLeft"24dp"
    android:paddingRight"24dp"

    android:layout_marginTop"8dp"

    android:layout_marginStart"40dp"
    android:layout_marginLeft"40dp"
    android:layout_marginEnd"40dp"
    android:layout_marginRight"40dp"
    app:layout_constraintTop_toBottomOf"@+id/errorMessageTitleTextView"
    app:layout_constraintEnd_toEndOf"parent"
    app:layout_constraintStart_toStartOf"parent"
    android:text""/>

Solution

To check if the text of a TextView has been ellipsized you can create your custom matcher like this one:

fun ellipsized()  object : TypeSafeMatcher<View>() {
    override fun describeTo(description: Description) {
        description.appendText("with ellipsized text")
    }

    override fun matchesSafely(v: View): Boolean {
        if (!(v is TextView)) {
            return false
        }
        val textView: TextView  v
        val layout: Layout  textView.getLayout()
        val lines  layout.lineCount
        if (lines > 0) {
            val ellipsisCount  layout.getEllipsisCount(lines - 1)
            if (ellipsisCount > 0) {
                return true
            }
        }

        return false
    }
}

And call it this way:

onView(withId(R.id.errorMessageTextView))
    .check(matches(ellipsized()))

Answered By – jeprubio

Leave a Comment