Android Espresso - установите флажок, если не установлен

У меня есть onView(withId(R.id.check_box)).perform(click()), но я хочу сделать это только в том случае, если флажок еще не установлен. Как я могу сделать это в эспрессо?

Ответ 1

Я также хотел переключить флажок/переключатель в зависимости от предыдущего состояния. Сначала я попытался включить переключатель ON, который был выключен:

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

... и это, чтобы отключить флажок, который был включен:

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

Однако это не работает, поскольку Espresso будет искать конкретное состояние переключения до того, как оно выполнит действие. Иногда вы не знаете, включено ли оно или выключено заранее.

Мое решение - использовать пользовательский ViewAction, чтобы отключить/включить любой проверяемый объект (Switch, Checkbox и т.д.), который не зависит от предыдущего состояния. Итак, если он уже включен, он останется включенным. Если он выключен, он переключится. Здесь ViewAction:

public static ViewAction setChecked(final boolean checked) {
    return new ViewAction() {
        @Override
        public Matcher<View> getConstraints() {
            return new Matcher<View>() {
                @Override
                public boolean matches(Object item) {
                    return isA(Checkable.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) {
            Checkable checkableView = (Checkable) view;
            checkableView.setChecked(checked);
        }
    };
}

И вот как вы его используете (в этом примере, когда вы хотите переключиться на ON):

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

Ответ 2

Кажется, это часть вашего теста, что флажок должен быть проверен.

Вы можете проверить это:

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

Если это не удастся, ваш тест завершится неудачно, что может быть хорошим в вашем случае. Затем вы можете выполнить требуемый щелчок после того, как этот случай будет соответствовать.

Если это не та ситуация, которую вы хотите, можете ли вы подробнее объяснить, что вы пытаетесь сделать в этом тесте эспрессо?

Ответ 3

В коде есть что-то вроде этого:

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

Ответ 4

У меня была та же проблема, что написал собственный 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())

теперь я могу быть уверен, что найденный переключатель всегда не отмечен, независимо от того, был ли он отмечен или не отмечен раньше.