Obtenga la actividad actual en la prueba de instrumentación de Android
Mi MainActivity en mi aplicación de Android comprueba si el usuario está conectado (esto se almacena en SharedPreferences) y si no lleva al usuario a LoginActivity. Estoy intentando probar esto usando el código siguiente
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> { private static final int TIME_OUT = 5000; /* miliseconds */ private MainActivity mMainActivity; private Instrumentation mInstrumentation; private SharedPreferences mLoginPrefs; public MainActivityTest() { super(MainActivity.class); } protected void setUp() throws Exception { super.setUp(); setActivityInitialTouchMode(false); mMainActivity = getActivity(); mInstrumentation = getInstrumentation(); mLoginPrefs = mInstrumentation.getTargetContext().getSharedPreferences(LoginActivity.PREFS_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = mLoginPrefs.edit(); // User is not logged in, so it should be redirect to LoginActivity editor.putBoolean("logged_in", false); editor.commit(); } //... public void testC_OpenLoginActivityIfUserIsNotLoggedIn() { ActivityMonitor monitor = mInstrumentation.addMonitor(LoginActivity.class.getName(), null, false); Activity nextActivity = mInstrumentation.waitForMonitorWithTimeout(monitor, TIME_OUT); assertNotNull(nextActivity); nextActivity.finish(); SharedPreferences.Editor editor = mLoginPrefs.edit(); // Login the user so we can continue the tests editor.putBoolean("logged_in", true); editor.commit(); }
Pero esto no funciona, LoginActivity se abre, pero waitForMonitorWithTimeout nunca vuelve, así que me quedé atascado en LoginActivity (Necesito volver a MainActivity para hacer las otras pruebas).
- Reflexión Java: implementa la interfaz y pasa a otra clase
- Android gradle src / androidTest / res / diseño / mylayout.xml no se encuentra en mypackage.R
- Android: JSON Parser con tareas asíncronas (métodos GET y POST)
- Java, HttpURLConnection y configuración de la longitud del contenido
- Copiar archivo a carpeta de activos
Un código similar a esta Pregunta SO funciona para los clics del botón, pero esta actividad no está cargada por ningún clic, así que estoy pensando que tal vez no hay tiempo para que el monitor funcione.
Sólo necesito una forma de obtener la Actividad real para poder hacer una afirmación y hacer que termine de continuar mis pruebas.
Sólo otra cosa: Preferiría un método sin usar Robotium si es posible.
- ¿Cómo puedo mover una imagen de un punto a otro mediante Android Canvas?
- ¿Manera apropiada de despejar la tabla / la base de datos del reino?
- Fwrite () en C & readInt () en Java difieren en endianess
- Obtener el valor de campo con un cursor
- Java.text.ParseException: fecha inquebrantable
- Cómo acceder a una cadena utilizando un nombre de cadena dinámica en android (similar a eval en javascript)?
- Android - DownloadManager - Borrar descargas antiguas en cola
- Cómo hacer referencia a un archivo en carpeta sin procesar en Android
Con el fin de resolver su problema, primero eche un vistazo a los dos métodos más importantes para su prueba:
Instrumentation#addMonitor(java.lang.String, android.app.Instrumentation.ActivityResult, boolean) Instrumentation.ActivityMonitor#waitForActivity()
Según la referencia de la API de Android:
addMonitor
Agregue un nuevo Instrumentation.ActivityMonitor que se verificará cada vez que se inicie una actividad . El monitor se añade después de los existentes; el monitor será golpeado sólo si ninguno de los monitores existentes pueden manejar el intento.
waitForActivity
Bloquear hasta que se cree una actividad que coincida con este monitor, devolviendo la actividad resultante.
Ahora dejémoslo un poco más claro.
addMonitor debe ser llamado siempre antes de que se inicie la actividad esperada, nunca demasiado tarde.
waitForActivity debe ser llamado sólo después de que se inicie la actividad esperada, nunca demasiado temprano, ya que bloqueará.
Volver a su código:
Están llamando a ambos juntos, sin que nada mágico suceda entre ellos. Por lo tanto, es demasiado tarde para addMonitor, o demasiado pronto para waitForActivity.
ActivityMonitor monitor = mInstrumentation.addMonitor(LoginActivity.class.getName(), null, false); Activity nextActivity = mInstrumentation.waitForMonitorWithTimeout(monitor, TIME_OUT);
Si es demasiado pronto para llamar a waitForActivity, bloqueará y fallará hasta el tiempo de espera (porque la actividad esperada aún no se ha alcanzado) y nunca vería la actividad esperada iniciada.
Si es demasiado tarde para llamar a addMonitor, el monitoreo comienza después de que se inicie la actividad esperada, y la actividad esperada no se vuelve a iniciar desde entonces, por lo que waitForActivity se bloqueará debido a que no se ha alcanzado el monitor.
Así que la diferencia entre los dos casos es si la actividad esperada se inicia o no . Y para tu caso, creo que es demasiado tarde para llamar a addMonitor.
La solución es muy sencilla: basta con mover addMonitor a una posición suficientemente temprana antes de que inicie LoginActivity, tal vez moverlo al método setUp , como esto:
mInstrumentation = getInstrumentation(); ActivityMonitor monitor = mInstrumentation.addMonitor(LoginActivity.class.getName(), null, false);
BTW, para su caso, con tiempo de espera o sin tiempo de espera no importa.
No se olvide de quitar el monitor
después de que no es necesario más eg:
@Override protected void tearDown() throws Exception { mInstrumentation.removeMonitor(monitor); super.tearDown(); }
Estabas en el buen camino. El método que debe llamar es:
monitor.waitForActivityWithTimeout(TIME_OUT);
en lugar de
mInstrumentation.waitForMonitorWithTimeout(monitor, TIME_OUT);
- Android countdowntimer tick no es preciso
- Cómo hacer que cada ListItem vaya a una actividad diferente