¿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.

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?

La respuesta es súper simple. Sólo asegúrese de actualizar sus pruebas de espresso a Junit 4, y luego vea esta respuesta

  • La prueba de Android JUnit de Simpe se cuelga en Eclipse
  • Pruebas unitarias con Android Studio y Gradle?
  • Unidad de pruebas de aplicaciones de Android en Eclipse + jUnit - Prueba de ejecución falló: Prueba de ejecución incompleta. Se esperan 1 pruebas, recibidas 0
  • Prueba de la clase de comunicación con DB a través de DAO de ORMLite
  • Prueba de RxJava2 doOnComplete ()
  • Cómo ejecutar grupos de pruebas de unidad con gradle en Android
  • Prueba JUnit con Robolectric: java.lang.InstantiationException
  • Android Robolectric unidad de prueba de Marshmallow PermissionHelper
  • Tratando de probar un módulo de Android en la aplicación MultiDex, com.android.test.runner.MultiDexTestRunner no se reconoce
  • Android JUnit4 Pruebas - ¿Dónde obtener el contexto de?
  • Robolectric's Shadow Object y Mocking
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.