Android Studio 3.2。
我有一个活动.sidebar-mobile-transition {
width: 100%;
z-index: 0;
background-color: white;
position: fixed;
bottom: 0;
overscroll-behavior: none;
overflow-y: scroll;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.sidebar-mobile-header {
top: 0;
position: fixed;
height: 50px;
width: 100%;
background: black;
color: white;
z-index: 10;
-webkit-transform: translate3d(0,0,0);
}
,它显示项目列表(TradesActivity
)。该列表由Trader
显示。
我需要编写下一个Espresso测试。
如果RecyclerView
,则项目的背景颜色为红色。其他背景颜色为绿色。我按仓位找到交易者。
所以我的Espresso测试必须执行以下步骤:
trader.getRunning() == true
Espresso如何做到这一点?
这是我的解决方案。这是一个好的解决方案吗?
trader.running
我的自定义ViewAssertion的代码段:
@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))
}
但是我得到了错误:
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))
}
}
}
}
}
}
答案 0 :(得分:0)
您可以这样创建一个自定义匹配器:
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;
}
};
}
答案 1 :(得分:0)
您没有提供足够的信息来完整地回答您的问题,但这应该可以引导您正确的方向。我不得不提一下,我宁愿在测试期间创建特定条件,并在给定位置检查给定列表项,然后深入检查数据和视图。
匹配器(伪代码):
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));
答案 2 :(得分:0)
我找到了解决方法:
@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)))
}
}
答案 3 :(得分:0)
Daniel Beleza answer 有 Kotlin 版本:
private fun withIndex(matcher: Matcher<View>, index: Int): Matcher<View> {
return object : TypeSafeMatcher<View>() {
private var currentIndex = 0
override fun describeTo(description: Description?) {
description?.appendText("with index: ");
description?.appendValue(index);
matcher.describeTo(description);
}
override fun matchesSafely(view: View?): Boolean {
return matcher.matches(view) && currentIndex++ == index;
}
}
}