Cómo detener y reiniciar una actividad en una prueba de instrumentación de Android?
Estoy tratando de escribir una prueba de instrumentación de actividad de Android que se detiene ( onPause()
, luego onStop()
) y reinicia la actividad actual. Lo intenté
activity.finish(); activity = getActivity();
… pero eso no parece funcionar correctamente.
- Android Marshmallow Permisos de Pruebas
- Android en la aplicación de facturación sandbox
- Espresso prueba pegado / inactivo después de realizar (haga clic ()) en el botón en ViewAnimator
- ProviderTestCase2.getProvider () es nulo
- La forma más rápida de probar el código fuente de Android modificado?
El objetivo de la prueba es afirmar que los datos del formulario se almacenan durante el método onPause()
y vuelven a leer durante el método onStart()
. Funciona cuando se hace manualmente, pero la prueba falla, de la cual extraigo la conclusión de que activity.finish()
parece ser la forma incorrecta de detener y reiniciar una actividad.
Edit: Mi problema principal parece haber sido un problema de sincronización. Después de reiniciar la actividad, el corredor de prueba no esperó a que todos los manejadores de eventos terminaran. La línea siguiente detiene la ejecución de prueba hasta que la actividad está inactiva:
getInstrumentation().waitForIdleSync()
Además, eche un vistazo a la respuesta aceptada para obtener información más valiosa sobre el ciclo de vida.
- Saltar prueba para la variante de construcción específica en Android + Gradle?
- ¿Cómo puedo comprobar en Robotium que la aplicación ha terminado?
- Prueba de GPS en Android
- ¿Cómo puedo obtener identificadores, nombres o rutas x para elementos ui utilizados en una aplicación para móviles (Android / iOS) para pruebas de automatización móvil?
- Cómo generar html informe con gradle 1.12?
- IsolatedContext vs AndroidTestCase.getContext ()
- Soft teclado no está presente, no se puede ocultar el teclado - Appium android
- ¿Cómo probar la función de sincronización de ejecución en android?
Al llamar (o activar un cambio de orientación de pantalla):
activity.finish(); // old activity instance is destroyed and shut down. activity = getActivity(); // new activity instance is launched and created.
Causar la actividad pasa por el ciclo completo de recreación:
onPause() -> onStop() -> onDestroy() -> onCreate()
Lo que usted necesita es:
onPause() -> onStop() -> onRestart()
He expuesto la Instrumentation API recientemente y encontró un montón de actividad interesante ciclo de vida del método de disparo callActivityOnXXX (), la siguiente línea de código debe hacer lo complicado:
MyActivity myActivity = getActivity(); // make activity falling into restart phase: getInstrumentation().callActivityOnRestart(myActivity);
Diagrama del ciclo de vida de la actividad citando la guía oficial de dev:
Intenté llamar a .finish (), setActivity (null), getActivity () y reinicia la actividad, pero para mí no estaba restaurando el estado. Intenté todas las otras respuestas en SO, y cada otro método para hacer esto podría encontrar en línea, y ninguno de ellos funcionó para mí. Después de mucha experimentación encontré los siguientes trabajos (nb: requiere API nivel 11+):
getInstrumentation().runOnMainSync(new Runnable() { @Override public void run() { activity.recreate(); } }); setActivity(null); activity = getActivity();
Cuando hago esto, se crea una nueva instancia de actividad y también se crea una nueva instancia del fragmento que había adjuntado a la actividad anteriormente en la prueba, y tanto la actividad como el fragmento restauran su estado de la manera esperada.
No sé cómo funciona esto o por qué esto funciona, llegué a esta solución a través de prueba y error, y sólo lo he probado en un Nexus 4 corriendo KitKat. No puedo garantizar que simula correctamente una actividad recreativa, pero funcionó para mis propósitos.
Edit: En una fecha posterior me di cuenta de cómo funciona esto. getActivity () funciona mediante el registro de ganchos que reciben nuevas Actividades que se están creando, que capturan la nueva Actividad creada por activity.recreate (). setActivity(null)
era necesario para borrar el respaldo de caché interno getActivity, de lo contrario devolverá el antiguo y no buscará uno nuevo.
Puede ver cómo funciona esto al examinar el código fuente de las distintas clases de casos de prueba de las que se extiende.
Una buena manera de probar los eventos del ciclo de vida es a través de cambios en la orientación de la pantalla. En mi experiencia es una manera conveniente de bombproof el patrón onPause / onStart.
Tal vez u podría tratar de guardar el nombre de su actividad, terminarlo … y utilizar la reflexión para obtener una nueva instancia de la .class para la nueva intención de crear …
Cambie su código de la siguiente manera:
mActivity.finish(); setActivity(null); mActivity = this.getActivity();
Una explicación completa se puede encontrar en esta pregunta
- Android Proguard con tarro externo
- ¿Qué sucede con un hilo de Android después de destruir la actividad que lo creó?