Espresso 在自定义视图中找不到文本

Espresso not finding text inside of Custom View

假设我有一个从头开始构建的自定义视图,如下所示:

class CustomTextView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
    defStyleRes: Int = 0
) : View(context, attrs, defStyleAttr, defStyleRes) {

    private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        style = Paint.Style.FILL_AND_STROKE
        textSize = 48f
        color = Color.BLUE
        strokeWidth = 3f
    }

    override fun onDraw(canvas: Canvas?) {
        canvas?.drawText("Text from Custom view", width / 2f, height / 2f, paint)
    }
}

这是 Canvas 上非常简单的绘图文本。在片段布局中,我添加了一个 TextView 和我的 CustomText 视图,如下所示:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="32dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Text from Text View" />

    <com.example.testing.views.CustomTextView 
        android:layout_width="250dp"
        android:layout_height="32dp"
        android:layout_marginTop="10dp" />

</LinearLayout

我的浓缩咖啡测试文件如下所示:

@RunWith(AndroidJUnit4::class)
class MyFragmentTest {
    private lateinit var scenario: FragmentScenario<MyFragment>

    @Before
    fun setup() {
        scenario = launchFragmentInContainer(themeResId = R.style.Theme_Testing)
        scenario.moveToState(Lifecycle.State.STARTED)
    }

    @Test
    fun testNormalTextView() { // -> PASSED
        onView(withText("Text from Text View")).check(matches(isDisplayed()))
    }

    @Test
    fun testCustomTextView() { // -> FAILED NoMatchingView Exception
        onView(withText("Text from Custom View")).check(matches(isDisplayed()))
    }
}

当我 运行 在我的物理设备上进行测试时,它仅通过 testNormalTextView 但在 testCustomTextView 上失败了。如何使用自定义视图使这些 Espresso 测试通过?

根据官方文档,withText()viewMatcher 与 Textviews 一起使用。

Returns a matcher that matches TextView based on its text property value.

在您的情况下,您的自定义视图正在扩展 View class。

以下是我建议的两种方式。

  1. 使您的自定义视图扩展 TextView。 [如果您的要求是仅访问具有特定文本的视图,而不管它的 id]
  2. 使用 withId() viewMatcher 而不是 withText(),传递在 xml 布局中给定的自定义视图的 ID。您需要在 xml 中为您的自定义视图提供 id。 [如果你想检查具有特定 ID 的视图,而不是它包含的文本]

在你的xml

   <com.example.testing.views.CustomTextView 
        android:id="@+id/my_custom_view"
        android:layout_width="250dp"
        android:layout_height="32dp"
        android:layout_marginTop="10dp" />

在你的测试函数中

    @Test
    fun testCustomTextView() {
        onView(withId(R.id.my_custom_view)).check(matches(isDisplayed()))
    }

更新:

对于 recyclerview,您可以使用 onData() 而不是 onView() 在参数中传递匹配器。 您可以找到有关测试的更多信息 adapterViews here