Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/184.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Espresso-如果未选中,请单击复选框_Android_Testing_Checkbox_Android Espresso - Fatal编程技术网

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

Android Espresso-如果未选中,请单击复选框,android,testing,checkbox,android-espresso,Android,Testing,Checkbox,Android Espresso,我有onView(带id(R.id.check_框))。执行(click()),但我只想在尚未选中该复选框的情况下执行此操作。我怎样才能在浓缩咖啡中做到这一点?您的代码中有类似的内容: @Rule public ActivityTestRule<ActivityMain> ActivityMainRule = new ActivityTestRule<>(ActivityMain.class); 这似乎是测试的一部分,需要选中复选框 您可以通过以下方式进行检查: onV

我有
onView(带id(R.id.check_框))。执行(click())
,但我只想在尚未选中该复选框的情况下执行此操作。我怎样才能在浓缩咖啡中做到这一点?

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

@Rule
public ActivityTestRule<ActivityMain> ActivityMainRule = new ActivityTestRule<>(ActivityMain.class);

这似乎是测试的一部分,需要选中复选框

您可以通过以下方式进行检查:

onView(withId(R.id.checkbox)).check(matches(not(isChecked())));
如果失败,你的测试将失败,这对你来说可能是好事。然后,您可以在此案例匹配后执行所需的单击


如果这不是你想要的情况,你能解释一下你在这项浓缩咖啡测试中想做什么吗?

我也有同样的问题,我自己写了一个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.checkbox)).check(matches(isNotChecked())).perform(scrollTo(), click());
…此选项用于关闭已打开的复选框:

onView(withId(R.id.checkbox)).check(matches(isChecked())).perform(scrollTo(), click());
但是,这不起作用,因为浓缩咖啡在执行操作之前会寻找特定的切换状态。有时候,你事先不知道它是开着还是关着

我的解决方案是使用自定义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);
        }
    };
}

正如@FrostRocket所建议的,但是是用Kotlin写的

我们定义了一个只能在可检查项上执行的自定义操作(如约束中所指定)。因此,我们安全地将视图强制转换为可检查的,以访问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
    }
}
fun setChecked(checked:Boolean)=对象:ViewAction{
val checkableViewMatcher=对象:BaseMatcher(){
覆盖有趣的匹配项(item:Any?):Boolean=isA(Checkable::class.java)。匹配项(item)
覆盖乐趣描述(描述:描述?){
description?.appendText(“是可检查的实例”)
}
}
override fun getConstraints():BaseMatcher=checkableViewMatcher
重写getDescription():字符串?=null
覆盖有趣的执行(uiController:uiController?,视图:视图){
val checkableView:Checkable=查看为可检查
checkableView.isChecked=已选中
}
}

根据谷歌的说法,这是不推荐的。这与浓缩咖啡的工作原理背道而驰,而且非常危险。我想在测试之前确保选中了复选框。它可能未被选中的原因是另一个测试未选中它。Espresso不应该能够设置视图的任何状态或以任何方式操纵视图。如果没有其他方法来组织你的测试,那么上一个答案就行了,但还是违反了浓缩咖啡的惯例。我建议您以一种使测试更加模块化的方式构建测试,这样它们就不必操纵任何视图@kyrax@kyrax你能接受我的答案吗?因为应该知道在浓缩咖啡测试中使用活动是非常糟糕的。@kryax我不知道为什么这是公认的答案,因为这并不能解决原来的问题。如果你想在不失败测试的情况下操作视图,请查看我发布的解决方案。很好,谢谢@FrostRocket。我唯一需要更改的是删除“scrollTo()”ViewAction,因为我错误地告知我的复选框不支持scrollTo:
onView(withId(R.id.global_search))。执行(setChecked(globalSearch));如您所见,我想将复选框设置为提供的“globalSearch”变量的值。我更新了答案,添加了复选框当前状态的检查,并仅在其状态不符合需要时更改它,以避免不必要的事件:
如果(checkableView.isChecked()!=checked){checkableView.setChecked(checked);}
setChecked的内部实现已经考虑到了这一点。这是一个很好的选择。但是,要知道,如果您在活动中根据所单击的复选框执行操作,则不会触发该操作。@Stonz2有一个很好的观点--
setChecked()
不会触发侦听器操作。要解决此问题,请单击视图:
if(checkableView.isChecked()!=选中)单击()。执行(uiController,视图)不要实现匹配器,而是扩展BaseMatcher
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));
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
    }
}