簡體   English   中英

如何使用特定視圖 Visible- Espresso 單擊 Recyclerview position

[英]How to click Recyclerview position with specific View Visible- Espresso

我正在使用 Espresso 為我的應用編寫 UI 測試。 屏幕顯示一個Recyclerview ,其中包含狀態為OPENCLOSED的商店列表。 根據數據, openTextViewclosedTextview默認顯示和隱藏。

以下是我的測試用例場景:

  • 檢查屏幕是否可見
  • 檢查 Recyclerview 是否可見
  • 檢查 Recyclerview 是否至少有一家商店處於OPEN狀態
  • 點擊第一個找到的OPEN店鋪
  • 檢查詳細信息屏幕是否顯示

問題:

我試圖單擊第一個OPEN狀態項,但它拋出異常。

下面是代碼

@Test
fun openShopTest() {

    onView(withText(“Shops")).check(matches(isDisplayed()))

    onView(withId(R.id.rvShops)).check(matches(isDisplayed()))

    //There is at least one open shop visible

    onView(withId(R.id.rvShops))
        .perform(RecyclerViewActions.scrollToHolder(first(withOpenText())))

    //User clicks on open shop

    onView(allOf(withId(R.id.rvShops), isDisplayed()))
        .perform(actionOnItem<ListAdapter.ListViewHolder>(withChild(withText(“Open”)), click()))

    //Screen with details appear

    onView(withText("Details”)).check(matches(isDisplayed()))

}

fun withOpenText(): Matcher<RecyclerView.ViewHolder> {
    return object :
        BoundedMatcher<RecyclerView.ViewHolder, ListAdapter.ListViewHolder>(
            ListAdapter.ListViewHolder::class.java
        ) {

        override fun describeTo(description: Description) {
            description.appendText("No ViewHolder found with Open Status Visible")
        }

        override fun matchesSafely(item: ListAdapter.ListViewHolder): Boolean {
            val openTextView = item.itemView.findViewById(R.id.openTextView) as TextView
            return openTextView.isVisible
        }
    }
}

以下是例外情況:

androidx.test.espresso.PerformException: Error performing 'performing ViewAction: single click on item matching: holder with view: has child: with text: is "Open"' on view '(with id: mypackagename:id/rvShops and is displayed on the screen to the user)'.
at androidx.test.espresso.PerformException$Builder.build(PerformException.java:82)
at androidx.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:79)
at androidx.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:51)
at androidx.test.espresso.ViewInteraction.waitForAndHandleInteractionResults(ViewInteraction.java:312)
at androidx.test.espresso.ViewInteraction.desugaredPerform(ViewInteraction.java:173)
at androidx.test.espresso.ViewInteraction.perform(ViewInteraction.java:114)
at mypackagename.MyUITest.openShopTest(MyUITest.kt:77)
... 32 trimmed
Caused by: androidx.test.espresso.PerformException: Error performing 'scroll RecyclerView to: holder with view: has child: with text: is "Open"' on view 'RecyclerView{id=2131231032, res-name=rvShops, visibility=VISIBLE, width=1080, height=2047, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=true, is-layout-requested=false, is-selected=false, layout-params=androidx.constraintlayout.widget.ConstraintLayout$LayoutParams@295fec9, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=12}'.
at androidx.test.espresso.PerformException$Builder.build(PerformException.java:82)
at androidx.test.espresso.contrib.RecyclerViewActions$ScrollToViewAction.perform(RecyclerViewActions.java:381)
at androidx.test.espresso.contrib.RecyclerViewActions$ActionOnItemViewAction.perform(RecyclerViewActions.java:221)
at androidx.test.espresso.ViewInteraction$SingleExecutionViewAction.perform(ViewInteraction.java:356)
at androidx.test.espresso.ViewInteraction.doPerform(ViewInteraction.java:248)
at androidx.test.espresso.ViewInteraction.access$100(ViewInteraction.java:63)
at androidx.test.espresso.ViewInteraction$1.call(ViewInteraction.java:153)
at androidx.test.espresso.ViewInteraction$1.call(ViewInteraction.java:150)
at java.util.concurrent.FutureTask.run(FutureTask.java:264)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8751)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
Caused by: java.lang.RuntimeException: Found 0 items matching holder with view: has child: with text: is "Open", but position -1 was requested.
at androidx.test.espresso.contrib.RecyclerViewActions$ScrollToViewAction.perform(RecyclerViewActions.java:361)

我試過什么?

  • 我有一個想法,也許openTextViewclosedTextview並不總是可見的,所以這可能是導致問題的原因。 我也嘗試讓兩者始終可見。

  • 我按照這個問題的答案中提到的步驟進行操作,但出現了同樣的問題。

需要什么?

  • 單擊openTextView可見的 Recyclerview 行
  • 獲取openTextView可見的行的openTextView 這樣我就可以使用atPosition function 並單擊該行。

有人可以幫我解決這個問題嗎?

任何幫助將不勝感激。

謝謝

這個想法是自定義 Espresso 的 View 操作。

object MyViewAction {
    fun clickChildViewWithIdAndText(id: Int, text: String): ViewAction {
        return object: ViewAction {
            override fun getConstraints(): Matcher<View> {
                return withText(text)
            }

            override fun getDescription(): String {
                return "Click on a child view with specified id and text"
            }

            override fun perform(uiController: UiController?, view: View) {
                val v: View = view.findViewById(id)
                v.performClick()
            }
        }
    }
}

onView(withId(R.id.rv_home)).perform(
      RecyclerViewActions.actionOnItemAtPosition<ListAdapter.ListViewHolder>(
          0,
          MyViewAction.clickChildViewWithIdAndText(R.id.tv_id, "OPEN")
      )
);

順便說一句,您可以使用一些構建在 Espresso 之上的強大測試庫,例如BaristaKakao 它可以幫助您的測試代碼更具可讀性和優雅性。

例如,您可以僅用一行代碼斷言列表視圖中顯示在 position x 的項目和文本 y

import com.adevinta.android.barista.assertion.BaristaListAssertions.assertDisplayedAtPosition

assertDisplayedAtPosition(R.id.rv_list, x, R.id.tv_id, y)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM