我有一个onView(withId(R.id.check_box)).perform(click())
,但只有在复选框未被选中时才想执行此操作。在Espresso中如何实现?
我有一个onView(withId(R.id.check_box)).perform(click())
,但只有在复选框未被选中时才想执行此操作。在Espresso中如何实现?
我也希望根据之前的状态来切换checkbox/switch。一开始,我尝试这样将关闭的复选框切换为打开:
onView(withId(R.id.checkbox)).check(matches(isNotChecked())).perform(scrollTo(), click());
...并使用此方法将已打开的复选框切换为关闭:
onView(withId(R.id.checkbox)).check(matches(isChecked())).perform(scrollTo(), click());
然而,这并不起作用,因为Espresso在执行操作之前将查找特定的切换状态。有时,您事先不知道它是开还是关。
我的解决方案是使用自定义ViewAction关闭/打开任何可选对象(开关、复选框等),而不依赖于先前的状态。所以,如果它已经开启,它将保持开启状态。如果它关闭了,它将切换为开启状态。以下是ViewAction:
public static ViewAction setChecked(final boolean checked) {
return new ViewAction() {
@Override
public BaseMatcher<View> getConstraints() {
return new BaseMatcher<View>() {
@Override
public boolean matches(Object item) {
return isA(Checkable.class).matches(item);
}
@Override
public void describeMismatch(Object item, Description mismatchDescription) {}
@Override
public void describeTo(Description description) {}
};
}
@Override
public String getDescription() {
return null;
}
@Override
public void perform(UiController uiController, View view) {
Checkable checkableView = (Checkable) view;
checkableView.setChecked(checked);
}
};
}
以下是如何使用它的步骤(在这个例子中,当你想要切换到“开启”状态时):
onView(withId(R.id.toggle)).perform(scrollTo(), setChecked(true));
正如@FrostRocket建议的那样,但使用Kotlin编写。
我们定义了一个自定义操作,只能在可选项上执行(如约束所指定)。因此,我们安全地将视图强制转换为Checkable类型,以访问setCheckable方法。
fun setChecked(checked: Boolean) = object : ViewAction {
val checkableViewMatcher = object : BaseMatcher<View>() {
override fun matches(item: Any?): Boolean = isA(Checkable::class.java).matches(item)
override fun describeTo(description: Description?) {
description?.appendText("is Checkable instance ")
}
}
override fun getConstraints(): BaseMatcher<View> = checkableViewMatcher
override fun getDescription(): String? = null
override fun perform(uiController: UiController?, view: View) {
val checkableView: Checkable = view as Checkable
checkableView.isChecked = checked
}
}
看起来这是你的测试的一部分,需要勾选复选框。
你可以通过以下方式检查:
onView(withId(R.id.checkbox)).check(matches(not(isChecked())));
onView(withId(R.id.checkBox_tea)).check(matches(isNotChecked())).perform(click()).check(matches(isChecked()));
对我来说完美地工作。
@Rule
public ActivityTestRule<ActivityMain> ActivityMainRule = new ActivityTestRule<>(ActivityMain.class);
尝试
if (!ActivityMainRule.getActivity().findViewById(R.id.check_box).isChecked()) {
onView(withId(R.id.check_box)).perform(click())
}
我曾经遇到过同样的问题,编写了自己的ViewAction,始终取消选中我的SwitchCompat
class UncheckViewAction implements ViewAction{
@Override
public Matcher<View> getConstraints() {
return new Matcher<View>() {
@Override
public boolean matches(Object item) {
return isA(SwitchCompat.class).matches(item);
}
@Override
public void describeMismatch(Object item, Description mismatchDescription) {
}
@Override
public void _dont_implement_Matcher___instead_extend_BaseMatcher_() {
}
@Override
public void describeTo(Description description) {
}
};
}
@Override
public String getDescription() {
return null;
}
@Override
public void perform(UiController uiController, View view) {
SwitchCompat scView = (SwitchCompat) view;
scView.setChecked(false);
}
}
并像这样使用它:
onView(withId(R.id.check_box)).perform(new UncheckViewAction())
onView(withId(R.id.global_search)).perform(setChecked(globalSearch));
正如您所看到的,我想将复选框设置为提供的“globalSearch”变量的值。 - yvolkif (checkableView.isChecked() != checked) { checkableView.setChecked(checked); }
- yvolksetChecked()
不会触发监听器操作。为了解决这个问题,可以点击视图:if (checkableView.isChecked() != checked) click().perform(uiController, view);
- Jerry101