2015-12-03 22 views
15

Sto provando a testare il testo di una ActionPage usando Espresso. Tuttavia, quando eseguo l'Ui Automation Viewer, posso vedere che ActionPage viene visualizzato come una vista invece di un ActionView e non ha un TextView.Android Espresso Ui Test verifica il testo dell'etichetta di ActionPage

Ho cercato il controllo per il testo ActionLabel come questo, ma che non funziona:

onView(withClassName(equalToIgnoringCase("android.support.wearable.view.ActionLabel"))).check(matches(withText("MyText"))); 

Ho un ID per il mio ActionPage in modo da poter trovare con onView(withId(R.id.actionPage)) ma non so come accedere suoi figli per ottenere il testo di ActionLabel. Ho provato a scrivere un matcher personalizzato, ma anche questo non funziona:

onView(withId(R.id.actionPage)).check(matches(withChildText("MyText"))); 

static Matcher<View> withChildText(final String string) { 
     return new BoundedMatcher<View, View>(View.class) { 
      @Override 
      public boolean matchesSafely(View view) { 
       ViewGroup viewGroup = ((ViewGroup) view); 
       //return (((TextView) actionLabel).getText()).equals(string); 
       for(int i = 0; i < view.getChildCount(); i++){ 
        View child = view.getChildAt(i); 
        if (child instanceof TextView) { 
         return ((TextView) child).getText().toString().equals(string); 
        } 
       } 
       return false; 
      } 

      @Override 
      public void describeTo(Description description) { 
       description.appendText("with child text: " + string); 
      } 
     }; 
    } 

Qualcuno potrebbe darmi una mano, l'ActionLabel non sembra avere un id per sé e la sua non è una TextView ... come posso controllare il testo al suo interno?

+------>FrameLayout{id=-1, visibility=VISIBLE, width=320, height=320, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1} 
| 
+------->ActionPage{id=2131689620, res-name=actionPage, visibility=VISIBLE, width=320, height=320, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2} 
| 
+-------->ActionLabel{id=-1, visibility=VISIBLE, width=285, height=111, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=17.0, y=209.0} 
| 
+-------->CircularButton{id=-1, visibility=VISIBLE, width=144, height=144, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=88.0, y=65.0} 

enter image description here

+0

È possibile aggiungere a livello di descrizione o ID del contenuto almeno uno di questi layout? Sarebbe molto più facile catturare – piotrek1543

risposta

6

È possibile utilizzare withParent con allOf:

onView(
    allOf(
     withParent(withId(R.id.actionPage)), 
     isAssignableFrom(ActionLabel.class))) 
    .check(matches(withActionLabel(is("MyText")))); 

Purtroppo ActionLabel non espone il suo testo via getText(), così invece dello standard withText() matcher, si deve scrivere un costume uno con riflessione:

private static Matcher<Object> withActionLabel(
    final Matcher<CharSequence> textMatcher) { 
    return new BoundedMatcher<Object, ActionLabel>(ActionLabel.class) { 
    @Override public boolean matchesSafely(ActionLabel label) { 
     try { 
     java.lang.reflect.Field f = label.getClass().getDeclaredField("mText"); 
     f.setAccessible(true); 
     CharSequence text = (CharSequence) f.get(label); 
     return textMatcher.matches(text); 
     } catch (NoSuchFieldException e) { 
     return false; 
     } catch (IllegalAccessException e) { 
     return false; 
     } 
    } 
    @Override public void describeTo(Description description) { 
     description.appendText("with action label: "); 
     textMatcher.describeTo(description); 
    } 
    }; 
} 

Maggiori informazioni: http://blog.sqisland.com/2015/05/espresso-match-toolbar-title.html

Si prega di inviare un bug per richiedere Google per aggiungere un metodo pubblico ActionLabel.getText() modo da poter testare senza riflessione.

+0

Grazie! Il problema è che 'ActionLabel' non è assegnabile a' TextView' e 'ActionLabel' non ha un metodo pubblico' getText() '. – AlexIIP

+0

'ActionLabel' è la tua vista personalizzata? Se è così, puoi aggiungere un metodo 'getText()' e scrivere un matcher personalizzato usando quello. Vedi il link del blog per un campione di corrispondenza personalizzato. – chiuki

+0

Non è, è una classe Android. http://developer.android.com/reference/android/support/wearable/view/ActionPage.html – AlexIIP