2015-08-06 2 views
4

J'essaie de tester mon application qui utilise ViewPager. Chaque page contient des fragments mais ces fragments ne sont pas toujours visibles. Je veux vérifier la visibilité d'un fragment dans la page actuellement visible.Test ViewPager avec plusieurs fragments en utilisant l'espresso android

onView(withId(R.id.container_weather)) 
    .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))); 

Mais le problème est que les regards espresso sont toutes les pages non seulement la page en cours et je reçois l'erreur suivante:

android.support.test.espresso.AmbiguousViewMatcherException: 'with id: eu.airpatrol.android:id/container_weather' matches multiple views in the hierarchy...

Répondre

5

vos tests échouent en raison de plusieurs éléments avec le même identifiant. Vous pouvez combiner les conditions en utilisant allOf(...). Ensuite, utilisez isDisplayed() pour vérifier que la vue correspondante est visible à l'écran. Ci-dessous l'exemple peut travailler:

onView(allOf(
    withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE), 
    withId(R.id.container_weather))) 
    .check(matches(isDisplayed())); 
+1

Merci pour votre réponse, j'ai essayé votre solution mais elle a toujours le même problème. J'ai deux pages et les deux contiennent ce fragment et pour une raison quelconque ont tous les deux la visibilité = VISIBLE dans la hiérarchie de vue. –

+0

Avez-vous du texte ou un élément enfant unique dans R.id.container_weather? Si oui, vous pouvez ajouter cette vérification dans 'allOf()'. – denys

+3

La seule différence entre les deux est la coordonnée y parce que les deux sont sur des pages différentes. :( –

1

Ran dans ce même problème. J'ai eu la chance parce que les hiérarchies de vue dans mon ViewPager peuvent être facilement identifiés par leurs frères et sœurs, donc je suis en mesure de résoudre ce en utilisant la hasSibling matcher, comme ceci:

onView(
    allOf(
     hasSibling(withId(R.id.some_sibling)), 
     withId(R.id.field_to_test) 
    ) 
).perform(replaceText("123")); 

pas une solution parfaite, car il peut être un peu fragile , mais dans mon cas, je pense que c'était un compromis acceptable.

0

J'ai eu le même problème, où je réutilisez la disposition des boutons et il me donnait un correspond à plusieurs points de vue à l'exception hiérarchie.

Ainsi, le travail facile autour, je l'ai fait était de créer 2 écrans différents et ont 2 méthodes différentes avec un texte différent.

  1. Prélever écran:

    public WithdrawScreen clickWithdraw() { 
        onView(allOf(withId(R.id.save_button), withText("Withdraw"))) 
         .perform(click()); 
        return this; 
    } 
    
  2. écran de dépôt:

    public DepositScreen clickDeposit() { 
        onView(allOf(withId(R.id.save_button), withText("Deposit"))) 
         .perform(click()); 
        return this; 
    } 
    

et dans mes tests, je crée une nouvelle instance des deux écrans et appeler les méthodes ci-dessus à base référence à l'écran qui est un peu facile à tester.

WithdrawScreen withdrawInstance = new WithdrawScreen(); 
withdrawInstance.clickWithdraw(); 

DepositScreen depositInstance = new DepositScreen(); 
depositInstance.clickDeposit(); 

Le point était qu'ils utilisaient même id - R.id.save_button pour le bouton et je remplaçais texte du bouton en fonction de la visibilité du fragment que nous sommes.

Espérons que ça aide.

1

J'ai eu le même problème, mais en utilisant la condition isCompletelyDisplayed() a résolu ce problème car il ne prend en compte que les vues à l'écran.

Donc, quelque chose comme cela devrait fonctionner:

onView(allOf(withId(R.id.container_weather), isCompletelyDisplayed())) 
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))); 

Note: isDisplayed() fonctionne aussi dans certains cas, mais il faut aussi des vues hors écran en compte et ne fonctionnera pas si le ViewPager a une autre page pr fragment chargé avec le même id de vue.