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

时间:2016-06-14 18:12:09

标签: android testing checkbox android-espresso

我有onView(withId(R.id.check_box)).perform(click()),但如果尚未选中复选框,我只想这样做。我怎么能在浓缩咖啡中做到这一点?

5 个答案:

答案 0 :(得分:25)

我还想根据它的先前状态切换复选框/开关。首先,我试着在一个关闭的复选框上切换:

onView(withId(R.id.checkbox)).check(matches(isNotChecked())).perform(scrollTo(), click());

...这样可以关闭一个ON的复选框:

onView(withId(R.id.checkbox)).check(matches(isChecked())).perform(scrollTo(), click());

然而,这不起作用,因为Espresso将在执行操作之前寻找特定的切换状态。有时,您事先不知道它是开启还是关闭。

我的解决方案是使用自定义ViewAction关闭/打开任何不依赖于先前状态的可检查对象(Switch,Checkbox等)。因此,如果它已经开启,它将保持开启状态。如果它关闭,它将切换为ON。这是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));

答案 1 :(得分:2)

就像@FrostRocket建议的那样,但用Kotlin编写。

我们定义了只能对可检查项目执行的自定义操作(如约束中所指定)。因此,我们安全地将视图强制转换为Checkable以访问setCheckable方法。

class MainActivity : AppCompatActivity() {

    private val navigationBottomBar by lazy { activity_main__navigation_view__bottom_bar }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setUpNavigation()
    }

    private fun setUpNavigation() {
        val navController = Navigation.findNavController(this, R.id.activity_main__graph__nav_host)
        NavigationUI.setupWithNavController(navigationBottomBar, navController)
    }
}

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

这似乎是您测试的一部分,需要检查复选框。

您可以通过以下方式查看:

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

如果失败,您的测试将失败,这可能对您的情况有利。然后,您可以在此案例匹配后执行所需的单击。

如果这不是你想要的情况,你能解释一下你在Espresso测试中想要做些什么吗?

答案 4 :(得分:0)

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

现在我可以确定找到的开关总是未经检查,无论之前是否已选中或未选中。