Android: Espresso: Как получить предмет на определенной позиции RecyclerView? - PullRequest
0 голосов
/ 12 апреля 2019

Android Studio 3.2.

У меня есть активность TradesActivity, которая показывает список предметов (Trader).Этот список показывает RecyclerView.

Мне нужно написать следующий тест эспрессо.если trader.getRunning() == true, то цвет фона элемента красный .Еще цвет фона зеленый .Я нахожу трейдера по позиции.

Так что мой тест эспрессо должен пройти следующие шаги:

  1. Получить трейдера определенной позиции (например, 6)
  2. Чек trader.running
  3. если это правда, тогда проверьте фон textView

Как я могу сделать это с помощью Espresso?

Вот мое решение.Это хорошее решение?

    @Rule
    @JvmField
    var activityActivityTestRule = ActivityTestRule(TradersActivity::class.java)

@Test
fun itemList_itemContainerBackgrounColor() {
    // scroll to position
    onView(withId(R.id.tradersRecyclerView))
            .perform(RecyclerViewActions.actionOnItemAtPosition<RecyclerView.ViewHolder>(CHECK_ITEM_LIST_POS, swipeLeft()))
    // check
    onView(withId(R.id.tradersRecyclerView)).check(hasCorrectBackgroundColorAtPosition(CHECK_ITEM_LIST_POS, R.id.itemContainer))
}

фрагмент моего пользовательского ViewAssertion:

class TraderViewAssertion {

    companion object {
        fun hasCorrectBackgroundColorAtPosition(position: Int, @IdRes resId: Int): ViewAssertion {
            return object : ViewAssertion {

                override fun check(view: View, exception: NoMatchingViewException) {
                    if (view !is RecyclerView) {
                        throw exception
                    }
                    val trader = (view.adapter as TraderListItemAdapter).getItem(position) as Trader
                    val itemView = view.findViewHolderForAdapterPosition(position)!!.itemView.findViewById<View>(resId) as TextView
                    val itemViewColorDrawable = itemView.getBackground() as ColorDrawable
                    val colorCode = itemViewColorDrawable.color
                    if (trader.isRunning) {
                        if (DateUtil.getDiffMinutes(Date(trader.last_iteration_time), Date()) > 1) {
                            Assert.assertTrue("Wrong color at position $position", (colorCode == R.color.trade_error_color))
                        } else {
                            Assert.assertTrue("Wrong color at position $position", (colorCode == R.color.trade_running_color))
                        }
                    } else {
                        Assert.assertTrue("Wrong color at position $position", (colorCode == R.color.trade_not_running_color))
                    }
                }
            }
        }
    }
}

Но я получаю ошибку:

java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter exception
at com.myproject.custom.assertion.TraderViewAssertion$Companion$hasCorrectBackgroundColorAtPosition$1.check(TraderViewAssertion.kt)
at androidx.test.espresso.ViewInteraction$SingleExecutionViewAssertion.check(ViewInteraction.java:419)
at androidx.test.espresso.ViewInteraction$2.call(ViewInteraction.java:282)
at androidx.test.espresso.ViewInteraction$2.call(ViewInteraction.java:268)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Ответы [ 3 ]

0 голосов
/ 12 апреля 2019

Вы не предоставили достаточно информации для полного ответа на ваш вопрос, но это должно привести вас в правильном направлении. Я должен упомянуть, что предпочел бы создать определенное условие во время теста и проверить данный элемент списка в данной позиции, а затем погрузиться в проверку как данных, так и представления.

Matcher (псевдокод):

    public static ViewAssertion hasCorrectBackgroundColorAtPosition(int position, @IdRes int id) {
        return new ViewAssertion() {
            @Override
            public void check(View view, NoMatchingViewException exception) {
                if (!(view instanceof RecyclerView)) {
                    throw exception;
                }

                RecyclerView rv = (RecyclerView) view;
                Trader item = ((YourAdapter) rv.getAdapter()).getItem(position);

                View itemView = rv.findViewHolderForAdapterPosition(position).itemView.findViewById(id);

        if(item.running) {
                Assert.assertTrue(
                        "Wrong color at position " + position,
                        itemView.getBackground().getColor() == R.color.colorA
                );
                } else {
                Assert.assertTrue(
                        "Wrong color at position " + position,
                        itemView.getBackground().getColor() == R.color.colorB
                );
                }

            }
        };
    }

Как использовать:

onView(yourRecyclerView).check(hasCorrectBackgroundColorAtPosition(123, R.id.yourTextViewId));
0 голосов
/ 13 апреля 2019

Я нашел решение:

 @Test
    fun itemList_itemContainerBackgrounColor() {
        // scroll to position
        onView(withId(R.id.tradersRecyclerView))
                .perform(RecyclerViewActions.actionOnItemAtPosition<RecyclerView.ViewHolder>(CHECK_ITEM_LIST_POS, swipeLeft()))
        // check
        val recyclerView = activityActivityTestRule.activity.findViewById<View>(R.id.tradersRecyclerView) as RecyclerView
        val trader = (recyclerView.adapter as TraderListItemAdapter).getItem(CHECK_ITEM_LIST_POS) as Trader
        val itemContainer = recyclerView.findViewHolderForAdapterPosition(CHECK_ITEM_LIST_POS)!!.itemView.findViewById<View>(R.id.itemContainer) as ConstraintLayout
        val colorCode = (itemContainer.background.current as ColorDrawable).color
        if (trader.isRunning) {
            if (DateUtil.getDiffMinutes(Date(trader.last_iteration_time), Date()) > 1) {
                Assert.assertTrue("Wrong color at position $CHECK_ITEM_LIST_POS", (colorCode == ContextCompat.getColor(itemContainer.context, R.color.trade_error_color)))
            } else {
                Assert.assertTrue("Wrong color at position $CHECK_ITEM_LIST_POS", (colorCode == ContextCompat.getColor(itemContainer.context, R.color.trade_running_color)))
            }
        } else {
            Assert.assertTrue("Wrong color at position $CHECK_ITEM_LIST_POS", (colorCode == ContextCompat.getColor(itemContainer.context, R.color.trade_not_running_color)))
        }
    }
0 голосов
/ 12 апреля 2019

Вы можете сделать это, создав пользовательский сопоставитель следующим образом:

public static Matcher<View> withIndex(final Matcher<View> matcher, final int index) {
return new TypeSafeMatcher<View>() {
    int currentIndex = 0;

    @Override
    public void describeTo(Description description) {
        description.appendText("with index: ");
        description.appendValue(index);
        matcher.describeTo(description);
    }

    @Override
    public boolean matchesSafely(View view) {
        return matcher.matches(view) && currentIndex++ == index;
    }
};

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...