¿Cómo volver a ejecutar la prueba fallada en Espresso? – lluvia de ideas
Estoy tratando de averiguar, cómo volver a ejecutar pruebas fallidas con el uso de Espresso. Creo que es un poco más complicado desde el caso de prueba de JUnit común, ya que es necesario restaurar el estado de la aplicación desde antes del inicio de la prueba.
Mi enfoque es crear mi propia ActivityTestRule por lo que acaba de copiar todo el código de esta clase y lo llamó MyActivityTestRule.
- ¿Intentar ejecutar Android JUnit pruebas en Eclipse falla?
- Diferencia entre el método runOnUiThread () y la anotación @UiThreadTest
- Cómo escribir una prueba de unidad para un controlador de excepción de subprocesos no detectados.
- Prueba de unidad de Android no se burla
- Cómo proporcionar archivos de datos para las pruebas de unidad de Android
En caso de pruebas de instrumentación, la regla también necesitará información de cómo queremos iniciar nuestra actividad. Prefiero lanzarlo yo mismo en lugar de tener ambiente para hacerlo por mí. Así por ejemplo:
@Rule public MyActivityTestRule<ActivityToStartWith> activityRule = new MyActivityTestRule<>( ActivityToStartWith.class, true, false );
Así que también iniciar mi actividad en el método de anotación @Before:
@Before public void setUp() throws Exception { activityRule.launchActivity(new Intent()); }
Y hacer limpieza en @After método de anotación:
@After public void tearDown() throws Exception { cleanUpDataBaseAfterTest(); returnToStartingActivity(activityRule); }
Esos métodos – setUp (), tearDown () son esenciales para ser llamados antes / después de cada prueba – para asegurar que el estado de la aplicación durante el inicio de la prueba es correcto.
Dentro de MyActivityTestRule he hecho pocas modificaciones hasta ahora. Lo primero es cambiar el método de aplicación de:
@Override public Statement apply(final Statement base, Description description) { return new ActivityStatement(super.apply(base, description)); }
Es una cosa desconocida para mí, como ActivityStatement colocado en ActivityTestRule tiene método super.apply por lo que también envuelve la declaración de prueba en UiThreadStatement:
public class UiThreadStatement extends Statement { private final Statement mBase; private final boolean mRunOnUiThread; public UiThreadStatement(Statement base, boolean runOnUiThread) { mBase = base; mRunOnUiThread = runOnUiThread; } @Override public void evaluate() throws Throwable { if (mRunOnUiThread) { final AtomicReference<Throwable> exceptionRef = new AtomicReference<>(); getInstrumentation().runOnMainSync(new Runnable() { public void run() { try { mBase.evaluate(); } catch (Throwable throwable) { exceptionRef.set(throwable); } } }); Throwable throwable = exceptionRef.get(); if (throwable != null) { throw throwable; } } else { mBase.evaluate(); } } }
No mather lo que hago con mis pruebas Nunca puedo crear caso mRunOnUiThread boolean para ser verdad. Será cierto si dentro de mis casos de prueba, las pruebas con anotación @UiThreadTest estarán presentes – o eso es lo que entendí del código. Nunca sucede, sin embargo, no uso nada de eso, así que decidí ignorar este UiThreadStatement y cambiar MyActivityTestRule a:
@Override public Statement apply(final Statement base, Description description) { return new ActivityStatement(base); }
Y mis casos de prueba funcionan sin ningún problema. Gracias a todo lo que me queda – que envuelve mBase.evaluate () es:
private class ActivityStatement extends Statement { private final Statement mBase; public ActivityStatement(Statement base) { mBase = base; } @Override public void evaluate() throws Throwable { try { if (mLaunchActivity) { mActivity = launchActivity(getActivityIntent()); } mBase.evaluate(); } finally { finishActivity(); afterActivityFinished(); } } }
En general, launchActivity se llamará sólo si establezco en el 3er parámetro del valor del constructor ActivityTestRule true. Pero lanzar pruebas por mí mismo en setUp () por lo que nunca sucede.
De lo que he entendido mBase.evaluate () ejecuta mi código dentro del método de anotación @Test. También se detiene el caso de prueba durante lanzable ser arrojado. Eso significa que puedo capturarlo y reiniciarlo – como se propuso allí: ¿Cómo volver a ejecutar las pruebas fallidas de JUnit inmediatamente?
Y bien, hice algo así:
public class ActivityRetryStatement extends Statement { private final Statement mBase; private final int MAX_RUNS = 2; public ActivityRetryStatement(Statement base) { mBase = base; } @Override public void evaluate() throws Throwable { Throwable throwable = null; for (int i = 0; i < MAX_RUNS; i++) { try { mBase.evaluate(); // if you reach this lane that means evaluate passed // and you don't need to do the next run break; } catch (Throwable t) { // save first throwable if occurred if (throwable == null) { throwable = t; } // my try that didn't work launchActivity(testInitialIntent); // I've returned test to starting screen but // mBase.envaluate() didn't make it run again // it would be cool now to: // - invoke @After // - finish current activity // - invoke @Before again and start activity // - mBase.evaluate() should restart @Test on activity started again by @Before } } finishActivity(); afterActivityFinished(); // if 1st try fail but 2nd passes inform me still that there was error if (throwable != null) { throw throwable; } } }
Así que esos comentarios en el bloque catch son partes que no sé cómo hacer. Intenté ejecutar launchActivity en intención que usé en setUp () para ejecutar la prueba por primera vez. Pero mBase.evaluate () no lo hizo reaccionar (caso de prueba no ir de nuevo) – nada sucedió + realmente no me salvar allí creo. Me faltó algunas iniciaciones que hago en @SetUp, no fue llamado de nuevo. Realmente me gustaría encontrar una manera de reiniciar correctamente todo el ciclo de vida de la prueba @Before @Test @After una vez más. Tal vez algunos llamen a Instrumentation o TestRunner desde el código.
¿Alguna idea acerca de cómo se podría hacer?
- ¿Cómo probar la clase usando resolver contenido / proveedor?
- Creación de la notificación de InstrumentationTestCase
- ¿Cómo ejecutar una prueba JUnit4 simple en Android Studio 1.1?
- Obteniendo junit.framework.AssertionFailedError: No se encontraron pruebas en cuando se usa Unit y Mockito
- Prueba de unidad Android: connectedAndroidTest no ejecuta mi caso de prueba
- Error en el corredor al realizar pruebas con Robolectric
- ¿Cómo hacer simples pruebas junit de vainilla en android? Cómo obtener un error al hacer
- Uso de Mockito Matchers.any () con android.support.annotation.IntDef anotación personalizada
La respuesta es súper simple. Sólo asegúrese de actualizar sus pruebas de espresso a Junit 4, y luego vea esta respuesta