Ich habe onView(withId(R.id.check_box)).perform(click())
, aber ich möchte nur tun, wenn das Kontrollkästchen noch nicht aktiviert ist. Wie kann ich das in Espresso machen?Android Espresso - Klicken Sie auf das Kontrollkästchen, wenn nicht aktiviert
Antwort
Ich wollte auch eine Checkbox/Schalter je nach dem vorherigen Zustand wechseln. Zuerst habe ich versucht, diese auf ein Kontrollkästchen auszuwählen, die OFF war:
onView(withId(R.id.checkbox)).check(matches(isNotChecked())).perform(scrollTo(), click());
... und das ein Kontrollkästchen hin- und herzuschalten OFF, die ON war:
onView(withId(R.id.checkbox)).check(matches(isChecked())).perform(scrollTo(), click());
Allerdings bedeutet dies nicht funktioniert , da Espresso nach einem bestimmten Umschaltstatus sucht, bevor es die Aktion ausführt. Manchmal wissen Sie nicht, ob es vorher ein- oder ausgeschaltet ist.
Meine Lösung besteht darin, ein benutzerdefiniertes ViewAction zu verwenden, um jedes überprüfbare Objekt (Switch, Checkbox usw.), das nicht vom vorherigen Status abhängig ist, aus-/einzuschalten. Wenn es bereits eingeschaltet ist, bleibt es eingeschaltet. Wenn es ausgeschaltet ist, wird es eingeschaltet. Hier ist die 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);
}
};
}
Und hier ist, wie Sie es verwenden (in diesem Beispiel, wenn Sie auf ON umschalten wollen):
onView(withId(R.id.toggle)).perform(scrollTo(), setChecked(true));
Sie haben so etwas in Ihrem Code:
@Rule
public ActivityTestRule<ActivityMain> ActivityMainRule = new ActivityTestRule<>(ActivityMain.class);
Versuchen
if (!ActivityMainRule.getActivity().findViewById(R.id.check_box).isChecked()) {
onView(withId(R.id.check_box)).perform(click())
}
, die nicht nach Google wird empfohlen, es geht gegen wie Espresso Werke und ist sehr gefährlich https://youtu.be/isihPOY2vS4?t=4m12s –
Dies scheint Teil Ihres Tests zu sein, dass das Kontrollkästchen aktiviert werden muss.
Sie können dies durch:
onView(withId(R.id.checkbox)).check(matches(not(isChecked())));
Wenn dies nicht gelingt, wird Ihr Test nicht bestehen, was in Ihrem Fall gut sein kann. Dann können Sie den gewünschten Klick ausführen, nachdem dieser Fall übereinstimmt.
Wenn dies nicht die Situation ist, die Sie wollen, können Sie mehr erklären, was Sie in diesem Espresso-Test versuchen?
Ich möchte sicherstellen, dass das Kontrollkästchen aktiviert ist, bevor ich meinen Test mache. Der Grund, warum es möglicherweise deaktiviert ist, ist, weil ein anderer Test es deaktiviert hat. – kyrax
Es ist nicht möglich, dass Espresso in der Lage ist, Ansichten darzustellen oder Ansichten zu manipulieren. Wenn es keinen anderen Weg gibt, um Ihre Tests zu strukturieren, als die vorherige Antwort funktionieren würde, aber wieder gegen Espresso-Konventionen. Ich würde Ihnen empfehlen, Ihre Tests so zu strukturieren, dass sie modularer sind, so dass Sie keine Ansichten manipulieren mü[email protected] –
@kyrax Kannst du meine Antwort als akzeptiert akzeptieren, weil es bekannt sein sollte, dass die Verwendung einer Aktivität in Espressotests sehr sehr schlecht ist. –
hatte ich das gleiche Problem ein schrieb eine eigene Viewaction, die immer meine 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);
}
}
unchecks und verwendet es wie folgt aus:
onView(withId(R.id.check_box)).perform(new UncheckViewAction())
jetzt kann ich sicher sein, dass der gefundene Schalter immer deaktiviert, egal ob zuvor aktiviert oder deaktiviert wurde.
Dies sollte akzeptiert werden antworten! – jakubbialkowski
Perfekt, danke @FrostRocket Die einzige Sache, die ich ändern musste, war entfernen "scrollTo()" ViewAction, weil ich Fehler, dass ScrollTo nicht für mein Kontrollkästchen unterstützt: 'onView (withId (R.id. global_search)). perform (setChecked (globalSearch)); ' Wie Sie sehen, wollte ich das Kontrollkästchen auf den Wert der bereitgestellten" globalSearch "setzen var – yvolk
Ich aktualisierte die Antwort Prüfung des aktuellen Status des Kontrollkästchens und ändern es nur wenn der Status nicht so ist, um unnötige Ereignisse zu vermeiden: 'if (checkableView.isChecked()! = aktiviert) { checkableView.setChecked (checked); } ' – yvolk