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

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()); 
  • Android Espresso - Navegador Web
  • Prueba de intentos de Espresso de Android falla al azar con `` init () se debe llamar antes de usar este método ``
  • La ejecución de instrumentación falló debido a 'android.content.res.Resources $ NotFoundException'
  • Espresso congelación en la vista con bucle de animación
  • Configurar gradle para usar JUnit, Mockito, Hamcrest y Espresso
  • ¿Hay alguna manera de saber si se ha iniciado una actividad con Espresso?
  • Espresso no espera hasta que la actividad se destruye, antes de crear uno nuevo para la próxima prueba
  • Cómo rotar la actividad, quiero decir: el cambio de orientación de la pantalla con Espresso?
  • ActivityTestRule - cómo llamar al código antes de la aplicación onCreate
  • Espresso - compruebe si TextView existe en ListView
  • Mientras se ejecuta una prueba de Espresso utilizando el estudio de Android. Obtuve el siguiente error
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.