2016-06-14 9 views

Antwort

16

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)); 
+0

Dies sollte akzeptiert werden antworten! – jakubbialkowski

+0

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

+0

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

0

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())  
} 
+2

, die nicht nach Google wird empfohlen, es geht gegen wie Espresso Werke und ist sehr gefährlich https://youtu.be/isihPOY2vS4?t=4m12s –

1

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?

+0

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

+0

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] –

+0

@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. –

0

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.