Android Espresso -如果未选中,请单击复选框

jecbmhm3  于 2023-01-11  发布在  Android
关注(0)|答案(6)|浏览(122)

我有onView(withId(R.id.check_box)).perform(click()),但我只想在复选框没有选中的情况下执行此操作。如何在espresso中执行此操作?

mfpqipee

mfpqipee1#

我还想根据复选框/开关的先前状态来切换它。起初,我尝试打开一个关闭的复选框:

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);
        }
    };
}

下面是如何使用它(在本例中,当您想要切换到ON时):

onView(withId(R.id.toggle)).perform(scrollTo(), setChecked(true));
nue99wik

nue99wik2#

就像@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
    }
}
dphi5xsq

dphi5xsq3#

这似乎是测试的一部分,需要选中复选框。
您可以通过以下方式进行检查:

onView(withId(R.id.checkbox)).check(matches(not(isChecked())));

如果失败,测试也会失败,这在您的情况下可能是好的。然后,您可以在匹配后执行所需的单击。
如果这不是你想要的情况,你能解释一下你在这个咖啡测试中想做什么吗?

nfeuvbwi

nfeuvbwi4#

这个简单的解决方案可能会帮助您

onView(withId(R.id.checkBox_tea)).check(matches(isNotChecked())).perform(click()).check(matches(isChecked()));

对我来说太完美了。

4xrmg8kj

4xrmg8kj5#

您的代码中有类似这样的内容:

@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())    
}
txu3uszq

txu3uszq6#

我也遇到了同样的问题,我自己写了一个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())

现在我可以确定,找到的开关总是未选中的,无论它以前是选中还是未选中。

相关问题