android - 为什么没有通过回收站 View 测试?

标签 android kotlin android-recyclerview android-espresso

我已经编写了测试,测试是否显示了回收站 View (id:comments_view),但是它始终失败,我也不知道为什么。当我检查布局(id:cm)时,测试通过。

我有以下片段代码:

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

    <data>
        <variable
            name="post"
            type="com.example.kotlinpostapi.apiObjects.Post" />
        <variable
            name="comments"
            type="java.util.List" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".views.MainActivity"
        android:id="@+id/cm">


        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/comments_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

测试代码(我正在导航到另一个代码的片段):
@RunWith(AndroidJUnit4::class)
class CommentsListTest{

    @get: Rule
    val activityScenario = ActivityScenarioRule(MainActivity::class.java)

    @Test
    fun testCommentsAreDisplayed() {
        onView(withId(R.id.posts_view)).perform(actionOnItemAtPosition<PostAdapter.PostsViewHolder>(0, MyMatchers.clickChildView(R.id.show_comments_button)))

        //it fails
        onView(withId(R.id.comments_view)).check(matches(isDisplayed()))
        //it passes
        onView(withId(R.id.cm)).check(matches(isDisplayed()))
    }
}

怎么可能?如何测试回收者 View ?

最佳答案

RecyclerView的高度设置为wrap_content,如果看不见该元素至少90%,则测试将失败。

您可以做的是检查一个RecyclerView子级。

我首先声明以下方法:

fun nthChildOf(parentMatcher: Matcher<View?>, childPosition: Int): Matcher<View?>? {
    return object : TypeSafeMatcher<View>() {
        override fun describeTo(description: Description) {
            description.appendText("with $childPosition child view of type parentMatcher")
        }

        override fun matchesSafely(view: View): Boolean {
            if (view.parent !is ViewGroup) {
                return parentMatcher.matches(view.parent)
            }
            val group = view.parent as ViewGroup
            return parentMatcher.matches(view.parent) && group.getChildAt(childPosition) == view
        }
    }
}

使用此方法,您可以检查是否显示其第一个 child :
onView(nthChildOf(withId(R.id.comments_view), 0)).check(matches(isDisplayed()))

并检查其子元素中的一个元素(例如recyclerview_element_id):
onView(allOf(
        withId(R.id.recyclerview_element_id),
        isDescendantOfA(
                nthChildOf(withId(R.id.comments_view), 0))
)).check(matches(isDisplayed()))

如果您的RecyclerView扩展到屏幕的可用空间,您可以尝试做的另一件事是更改RecyclerView的布局,以设置所有约束,并将height设置为0dp:
<androidx.recyclerview.widget.RecyclerView
            android:id="@+id/comments_view"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

我有这种方式并做:
onView(withId(R.id.myRecyclerviewId)).check(matches(isDisplayed()))

为我工作。

关于android - 为什么没有通过回收站 View 测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62060216/

相关文章:

Android 在应用程序的不同部分重用 Activity

java - 无法覆盖乐趣完成()

java - Kotlin 1.3.61 无法解析函数文字上扩展属性的返回类型

android - 通过 fragments 在 recyclerview 和 toolbar 之间共享元素

android - 如何向回收站 View 的所有单元格添加填充

android - 如何在 Android 中以编程方式打开/更改 Google Ads 选择退出设置?

java - 高分辨率 Android 手机中的文本显示较小

android - 使用 ActiveAndroid 库存储 HashMap<String, Object>

android - Android:退出应用后,AlarmManager无法启动应用

android - 在 RecyclerView 适配器 notifyDataSetChanged() 之后未调用 onBindViewHolder