Selección de la vista secundaria en índice mediante Espresso
Con Espresso al usar una vista de widget personalizada con vistas de imagen secundaria, ¿qué tipo de Matcher puedo usar para seleccionar el n-ésimo niño? Ejemplo:
+--------->NumberSlider{id=2131296844, res-name=number_slider, visibility=VISIBLE, width=700, height=95, 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=10.0, y=0.0, child-count=7} | +---------->NumberView{id=-1, visibility=VISIBLE, width=99, height=95, 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=0.0, y=0.0} | +---------->NumberView{id=-1, visibility=VISIBLE, width=100, height=95, 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=99.0, y=0.0} | +---------->NumberView{id=-1, visibility=VISIBLE, width=100, height=95, 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=199.0, y=0.0} | +---------->NumberView{id=-1, visibility=VISIBLE, width=100, height=95, 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=299.0, y=0.0} | +---------->NumberView{id=-1, visibility=VISIBLE, width=100, height=95, 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=399.0, y=0.0} | +---------->NumberView{id=-1, visibility=VISIBLE, width=100, height=95, 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=499.0, y=0.0} | +---------->NumberView{id=-1, visibility=VISIBLE, width=100, height=95, 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=599.0, y=0.0}
- ¿Cómo esbozar imágenes de selección con intenciones Espresso?
- Android Espresso: espera que la actividad termine / empiece
- Android / Gradle prueba de espresso no iniciar actividad
- Prueba de intentos de Espresso de Android falla al azar con `` init () se debe llamar antes de usar este método ``
- Android Espresso: Ejecución de múltiples pruebas secuencialmente
- Prueba de Espresso de Android escamosa - Snackbar
- Cómo utilizar el espresso para presionar un botón AlertDialog
- Problemas con pruebas de instrumentos Espresso en los dispositivos de tiempo de ejecución de Dalvik
- Android Studio: conceder permiso entre la instalación de la prueba APK y las pruebas en ejecución con el corredor de prueba gráfica
- AndroidTest Falló al ejecutar desde la línea de comandos: app: connectedDebugAndroidTest
- Pruebas de instrumentación de Android con múltiples emuladores
- Prueba instrumental de una vista en MVP
- Android + Espresso + solicitud HTTP asíncrona -> cómo probar?
public static Matcher<View> nthChildOf(final Matcher<View> parentMatcher, final int childPosition) { return new TypeSafeMatcher<View>() { @Override public void describeTo(Description description) { description.appendText("with "+childPosition+" child view of type parentMatcher"); } @Override public boolean matchesSafely(View view) { if (!(view.getParent() instanceof ViewGroup)) { return parentMatcher.matches(view.getParent()); } ViewGroup group = (ViewGroup) view.getParent(); return parentMatcher.matches(view.getParent()) && group.getChildAt(childPosition).equals(view); } }; }
Para usarlo
onView(nthChildOf(withId(R.id.parent_container), 0).check(matches(withText("I am the first child"));
Para intentar mejorar un poco la solución de Maragues, he hecho algunos cambios.
La solución es crear un Matcher personalizado <View> que abra otro Matcher <View> para la vista primaria, y toma el índice de la vista secundaria para que coincida.
public static Matcher<View> nthChildOf(final Matcher<View> parentMatcher, final int childPosition) { return new TypeSafeMatcher<View>() { @Override public void describeTo(Description description) { description.appendText("position " + childPosition + " of parent "); parentMatcher.describeTo(description); } @Override public boolean matchesSafely(View view) { if (!(view.getParent() instanceof ViewGroup)) return false; ViewGroup parent = (ViewGroup) view.getParent(); return parentMatcher.matches(parent) && parent.getChildCount() > childPosition && parent.getChildAt(childPosition).equals(view); } }; }
Explicación detallada
Puede anular el método describeTo para dar una descripción fácil de entender del correlador añadiéndolo al argumento Descripción . También querrá propagar la llamada describeTo al matcher padre para que su descripción también se agregue.
@Override public void describeTo(Description description) { description.appendText("position " + childPosition + " of parent "); // Add this matcher's description. parentMatcher.describeTo(description); // Add the parentMatcher description. }
A continuación, debe reemplazar matchesSafely que determinará cuándo se ha encontrado una coincidencia en la jerarquía de vista. Cuando se llama con una vista cuyo padre coincide con el matador de padres proporcionado, compruebe que la vista es igual al niño en la posición proporcionada.
Si el padre no tiene un childCount mayor que la posición secundaria, getChildAt devolverá null y hará que la prueba se bloquee. Es mejor evitar el colapso y permitir que la prueba falle para que obtengamos un informe de prueba y un mensaje de error adecuados.
@Override public boolean matchesSafely(View view) { if (!(view.getParent() instanceof ViewGroup)) return false; // If it's not a ViewGroup we know it doesn't match. ViewGroup parent = (ViewGroup) view.getParent(); return parentMatcher.matches(parent) // Check that the parent matches. && parent.getChildCount() > childPosition // Make sure there's enough children. && parent.getChildAt(childPosition).equals(view); // Check that this is the right child. }
Si puede obtener la vista de los padres. Puede ser este enlace que define un matcher para obtener el primer hijo de una vista puede darle alguna pista.
public static Matcher<View> firstChildOf(final Matcher<View> parentMatcher) { return new TypeSafeMatcher<View>() { @Override public void describeTo(Description description) { description.appendText("with first child view of type parentMatcher"); } @Override public boolean matchesSafely(View view) { if (!(view.getParent() instanceof ViewGroup)) { return parentMatcher.matches(view.getParent()); } ViewGroup group = (ViewGroup) view.getParent(); return parentMatcher.matches(view.getParent()) && group.getChildAt(0).equals(view); } }; }
- Android – Navegación Ver el color del fondo del menú del elemento
- Cómo jugar videos de Youtube en Android Video View?