Espresso afirma que no es necesario Thread.sleep();
, pero mi código no funciona a menos que lo incluya. Me estoy conectando a una IP. Mientras se conecta, se muestra un cuadro de diálogo de progreso. Necesito sleep
esperar a que se cierre el diálogo. Este es mi fragmento de prueba donde lo uso:
IP.enterIP(); // fills out an IP dialog (this is done with espresso)
//progress dialog is now shown
Thread.sleep(1500);
onView(withId(R.id.button).perform(click());
He probado este código con y sin el Thread.sleep();
pero dice R.id.Button
que no existe. La única forma en que puedo hacer que funcione es durmiendo.
Además, he intentado reemplazar Thread.sleep();
con cosas como getInstrumentation().waitForIdleSync();
y todavía no tengo suerte.
¿Es esta la única forma de hacer esto? ¿O me estoy perdiendo algo?
Gracias por adelantado.
android
testing
android-espresso
Chad Bingham
fuente
fuente
Respuestas:
En mi opinión, el enfoque correcto será:
Y luego el patrón de uso será:
fuente
Gracias a AlexK por su increíble respuesta. Hay casos en los que es necesario retrasar el código. No está necesariamente esperando la respuesta del servidor, pero podría estar esperando a que se complete la animación. Personalmente, tengo un problema con Espresso idolingResources (creo que estamos escribiendo muchas líneas de código para una cosa simple), así que cambié la forma en que AlexK lo estaba haciendo en el siguiente código:
Entonces puede crear una
Delay
clase y poner este método en ella para acceder a ella fácilmente. Puede usarlo en su clase de prueba de la misma manera:onView(isRoot()).perform(waitFor(5000));
fuente
Thread.sleep()
Me encontré con este hilo cuando buscaba una respuesta a un problema similar en el que estaba esperando una respuesta del servidor y cambiando la visibilidad de los elementos en función de la respuesta.
Si bien la solución anterior definitivamente ayudó, finalmente encontré este excelente ejemplo de chiuki y ahora uso ese enfoque como mi opción cada vez que espero que ocurran acciones durante los períodos inactivos de la aplicación.
He añadido ElapsedTimeIdlingResource () a mi propia clase de servicios públicos, ahora se puede utilizar de manera efectiva que, como alternativa Express adecuada, y ahora uso es agradable y limpio:
fuente
I/TestRunner: java.lang.NoClassDefFoundError: fr.x.app.y.testtools.ElapsedTimeIdlingResource
error. Alguna idea. Yo uso Proguard pero con la ofuscación desactivada.-keep
declaración para las clases que no se encuentran para asegurarse de que ProGuard no las elimine como innecesarias. Más información aquí: developer.android.com/tools/help/proguard.html#keep-codeCreo que es más fácil agregar esta línea:
Espera una cantidad determinada de milisegundos (de uptimeMillis) antes de regresar. Similar a sleep (largo), pero no lanza InterruptedException; Los eventos interrupt () se aplazan hasta la siguiente operación interrumpible. No regresa hasta que haya transcurrido al menos el número especificado de milisegundos.
fuente
Puedes usar los métodos Barista:
BaristaSleepActions.sleep(2000);
BaristaSleepActions.sleep(2, SECONDS);
Barista es una biblioteca que envuelve Espresso para evitar agregar todo el código que necesita la respuesta aceptada. ¡Y aquí tienes un enlace! https://github.com/SchibstedSpain/Barista
fuente
Thread.sleep()
. ¡Lo siento! Fue en algunos de los primeros videos que Google hizo sobre Espresso pero no recuerdo cuál ... fue hace algunos años. ¡Lo siento! :·) ¡Oh! ¡Editar! Puse el enlace al video en el PR que abrí hace tres años. ¡Echale un vistazo! github.com/AdevintaSpain/Barista/pull/19Esto es similar a esta respuesta, pero usa un tiempo de espera en lugar de intentos y se puede encadenar con otras ViewInteractions:
Uso:
fuente
Soy nuevo en la codificación y Espresso, así que aunque sé que la solución buena y razonable es usar el ralentí, todavía no soy lo suficientemente inteligente para hacer eso.
Sin embargo, hasta que tenga más conocimientos, todavía necesito que mis pruebas se ejecuten de alguna manera, así que por ahora estoy usando esta solución sucia que hace varios intentos para encontrar un elemento, se detiene si lo encuentra y, si no, duerme brevemente y comienza de nuevo hasta alcanzar el número máximo de intentos (el mayor número de intentos hasta ahora ha sido de alrededor de 150).
Estoy usando esto en todos los métodos que encuentran elementos por ID, texto, padre, etc.
fuente
findById(int itemId)
método devolverá un elemento (que podría ser NULL) ya sea quewaitForElementUntilDisplayed(element);
devuelva verdadero o falso ... entonces, eso no está bienIdlingResource
Los s no son suficientes para mí debido a la granularidad de la tasa de sondeo de 5 segundos (demasiado grande para mi caso de uso). La respuesta aceptada tampoco me funciona (la explicación de por qué ya está incluida en el extenso feed de comentarios de esa respuesta). ¡Gracias por esto! Tomé tu idea e hice mi propia solución y funciona como un encanto.Espresso está diseñado para evitar llamadas a sleep () en las pruebas. Su prueba no debe abrir un diálogo para ingresar una IP, esa debe ser responsabilidad de la actividad probada.
Por otro lado, su prueba de IU debería:
La prueba debería verse así:
Espresso espera a que termine todo lo que está sucediendo tanto en el hilo de la interfaz de usuario como en el grupo AsyncTask antes de ejecutar las pruebas.
Recuerde que sus pruebas no deben hacer nada que sea responsabilidad de su aplicación. Debe comportarse como un "usuario bien informado": un usuario que hace clic, verifica que se muestra algo en la pantalla, pero, de hecho, conoce los ID de los componentes.
fuente
Debe usar Espresso Idling Resource, se sugiere en este CodeLab
Ejemplo de una llamada asincrónica del presentador
Dependencias
Para androidx
Repo oficial: https://github.com/googlecodelabs/android-testing
Ejemplo de IdlingResource: https://github.com/googlesamples/android-testing/tree/master/ui/espresso/IdlingResourceSample
fuente
Si bien creo que es mejor usar Idling Resources para esto ( https://google.github.io/android-testing-support-library/docs/espresso/idling-resource/ ), probablemente podría usar esto como alternativa:
y luego llámelo en su código como, por ejemplo:
en vez de
Esto también le permite agregar tiempos de espera para ver acciones y ver afirmaciones.
fuente
return new TimedViewInteraction(Espresso.onView(viewMatcher));
conreturn new TimedViewInteraction(Espresso.onView(viewMatcher).check(matches(isDisplayed())));
Mi utilidad repite la ejecución ejecutable o invocable hasta que pasa sin errores o lanza arrojables después de un tiempo de espera. ¡Funciona perfectamente para pruebas de Espresso!
Suponga que la última interacción de vista (clic en el botón) activa algunos subprocesos en segundo plano (red, base de datos, etc.). Como resultado, debería aparecer una nueva pantalla y queremos verificarla en nuestro próximo paso, pero no sabemos cuándo estará lista para ser probada.
El enfoque recomendado es forzar a su aplicación a enviar mensajes sobre estados de subprocesos a su prueba. A veces podemos usar mecanismos integrados como OkHttp3IdlingResource. En otros casos, debe insertar piezas de código en diferentes lugares de las fuentes de su aplicación (¡debe conocer la lógica de la aplicación!) Solo para probar el soporte. Además, deberíamos apagar todas tus animaciones (aunque es parte de la interfaz de usuario).
El otro enfoque está esperando, por ejemplo, SystemClock.sleep (10000). Pero no sabemos cuánto tiempo esperar e incluso los retrasos prolongados no pueden garantizar el éxito. Por otro lado, su prueba durará mucho.
Mi enfoque es agregar una condición de tiempo para ver la interacción. Por ejemplo, probamos que la nueva pantalla debería aparecer durante 10000 mc (tiempo de espera). Pero no esperamos y lo verificamos tan rápido como queremos (por ejemplo, cada 100 ms). Por supuesto, bloqueamos el hilo de prueba de esa manera, pero por lo general, es justo lo que necesitamos en tales casos.
Esta es mi fuente de clase:
https://gist.github.com/alexshr/ca90212e49e74eb201fbc976255b47e0
fuente
Este es un ayudante que estoy usando en Kotlin para pruebas de Android. En mi caso, estoy usando longOperation para imitar la respuesta del servidor, pero puedes ajustarlo a tu propósito.
fuente
Agregaré mi forma de hacer esto a la mezcla:
Llamado así:
Puede agregar parámetros como iteraciones máximas, longitud de iteración, etc. a la función suspendUntilSuccess.
Todavía prefiero usar recursos inactivos, pero cuando las pruebas funcionan debido a animaciones lentas en el dispositivo, por ejemplo, utilizo esta función y funciona bien. Por supuesto, puede colgarse hasta 5 segundos antes de fallar, por lo que podría aumentar el tiempo de ejecución de sus pruebas si la acción para tener éxito nunca tiene éxito.
fuente