ProgressBars y Espresso
Cuando tengo un ProgressBar en los diseños que se muestran cuando se ejecutan algunas pruebas de espresso – entonces me encuentro con:
Caused by: android.support.test.espresso.AppNotIdleException: Looped for 1670 iterations over 60 SECONDS. The following Idle Conditions failed .
¿Cuál es una buena manera de evitar esto? Encontré algunas cosas de hacking pero buscando una manera agradable
- openDrawer de espresso contrib está obsoleto
- Vista de la raíz compatible con Android Espresso
- ¿Por qué Espresso deja la aplicación una vez finalizada la prueba? Cómo detenerlo de hacer eso
- Cómo realizar un evento actionDone de EditText con Espresso
- Desinstalar la aplicación antes de iniciar la prueba
- "Java.lang.RuntimeException: No se pudo iniciar la intención" para la interfaz de usuario con ProgressBar indeterminado
- Appium vs Espresso para el marco de pruebas automatizado
- La interfaz de usuario de Espresso se ejecuta cuando ejecuto una sola prueba, pero falla cuando ejecuto un conjunto de pruebas
- Espresso Descripción de incompatibilidad de ViewMatcher personalizada que no aparece en el registro
- Toma de pantalla utilizando espresso
- Compruebe si se muestra un diálogo con Espresso
- Android Error Clase ref en clase pre-verificada resuelta a implementación inesperada
- Android Espresso. Cómo comprobar ErrorText en TextInputLayout
Tengo el mismo problema. No pude encontrar una solución totalmente elegante, pero también publicaré mi enfoque.
Lo que intenté hacer es anular el indeterminateDrawable
en el ProgressBar. Al tener un simple dibujable no se produce animación y la prueba de Espresso no se encuentra con el problema de Inactividad.
Lamentablemente, main
y androidTest
son tratados igual. No encontré una forma de anular los estilos para mi ProgressBar.
Ahora terminó en la combinación de algunas ideas de https://gist.github.com/Mauin/62c24c8a53593c0a605e#file-progressbar-java y Cómo detectar si la aplicación de Android está ejecutando la prueba de interfaz de usuario con Espresso .
Al principio creé las clases personalizadas de ProgressBar, una para depurar y otra para liberar. La versión de lanzamiento sólo llama a los súper constructores y no hace nada más. La versión de depuración anula el método setIndeterminateDrawable
. Con esto podría establecer un simple dibujable en lugar del animado.
Código de liberación:
public class ProgressBar extends android.widget.ProgressBar { public ProgressBar(Context context) { super(context); } public ProgressBar(Context context, AttributeSet attrs) { super(context, attrs); } public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } }
Código de depuración:
public class ProgressBar extends android.widget.ProgressBar { public ProgressBar(Context context) { super(context); } public ProgressBar(Context context, AttributeSet attrs) { super(context, attrs); } public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @SuppressWarnings("deprecation") @Override public void setIndeterminateDrawable(Drawable d) { if (isRunningTest()) { d = getResources().getDrawable(R.drawable.ic_replay); } super.setIndeterminateDrawable(d); } private boolean isRunningTest() { try { Class.forName("base.EspressoTestBase"); return true; } catch (ClassNotFoundException e) { /* no-op */ } return false; } }
Como se puede ver también he añadido un cheque si mi aplicación está ejecutando una prueba de Espresso, mientras que la clase que busco es la base de mis exámenes de Espresso.
Lo malo es que tienes que actualizar todo tu código para usar tu ProgressBar personalizado. Pero lo bueno es que su código de liberación no tiene un impacto importante con esta solución.
Si el ProgressBar
es invisible cuando se inicia la prueba, el Drawable
puede ser reemplazado por un ViewAction
personalizado:
// Replace the drawable with a static color onView(isAssignableFrom(ProgressBar.class)).perform(replaceProgressBarDrawable()); // Click a button (that will make the ProgressBar visible) onView(withText("Show ProgressBar").perform(click());
El ViewAction
personalizado:
public static ViewAction replaceProgressBarDrawable() { return actionWithAssertions(new ViewAction() { @Override public Matcher<View> getConstraints() { return isAssignableFrom(ProgressBar.class); } @Override public String getDescription() { return "replace the ProgressBar drawable"; } @Override public void perform(final UiController uiController, final View view) { // Replace the indeterminate drawable with a static red ColorDrawable ProgressBar progressBar = (ProgressBar) view; progressBar.setIndeterminateDrawable(new ColorDrawable(0xffff0000)); uiController.loopMainThreadUntilIdle(); } }); }
Tengo el problema similar. La prueba falló tan pronto como la primera llamada getActivity (). Por lo tanto, el estiramiento indeterminado de ProgressBar tiene que ser reemplazado después de que la actividad comenzó.
Application application = (Application)this.getInstrumentation().getTargetContext().getApplicationContext(); application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { //not here, it's too early } @Override public void onActivityStarted(Activity activity) { //find the progressBar in your activity ProgressBar progressBar = ((ProgressBar) activity.findViewById(R.id.progress_bar)); if(progressBar != null) { //replace progress bar drawable as not animated progressBar.setIndeterminateDrawable(new ColorDrawable(0xffff0000)); } } @Override public void onActivityResumed(Activity activity) { } @Override public void onActivityPaused(Activity activity) { } @Override public void onActivityStopped(Activity activity) { } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } @Override public void onActivityDestroyed(Activity activity) { } }); //Now you can start the activity getActivity();
Basado en la solución de Thomas R. , otro enfoque es cambiar el drawable del ProgressBar en la prueba, para evitar modificar el código de producción.
Ejemplo:
Activity activity = startActivity(); // override progress bar infinite animation with a simple image ProgressBar progressBar = (ProgressBar) activity.findViewById(R.id.loading_progressbar); progressBar.setIndeterminateDrawable(activity.getDrawable(android.R.drawable.ic_lock_lock)); // click on the button that triggers the display of the progress bar onView(withId(R.id.login_button)).perform(click());