2015-06-16 23 views
9

Abbiamo alcuni test dell'interfaccia utente relativi alle funzionalità della fotocamera e, dopo aver effettuato il passaggio da InstrumentationTestRunner a AndroidJUnitRunner come parte del nostro passaggio a Espresso/JUnit4, non possiamo più eseguire il nostro test esistenti in modo affidabile a causa di RuntimeException frequenti quando chiamiamo getActivity():I test dell'interfaccia utente Android esistenti hanno smesso di funzionare dopo il passaggio a AndroidJUnitRunner

java.lang.RuntimeException: Could not launch intent Intent { flg=0x14000000 cmp=com.cookbrite.dev/com.cookbrite.ui.ReceiptCaptureActivity (has extras) } within 45 seconds. Perhaps the main thread has not gone idle within a reasonable amount of time? There could be an animation or something constantly repainting the screen. Or the activity is doing network calls on creation? See the threaddump logs. For your reference the last time the event queue was idle before your activity launch request was 1434471981236 and now the last time the queue went idle was: 1434471981236. If these numbers are the same your activity might be hogging the event queue. 
at android.support.test.runner.MonitoringInstrumentation.startActivitySync(MonitoringInstrumentation.java:315) 
at android.test.InstrumentationTestCase.launchActivityWithIntent(InstrumentationTestCase.java:119) 
at android.test.ActivityInstrumentationTestCase2.getActivity(ActivityInstrumentationTestCase2.java:106) 
at com.cookbrite.step2_functional.ui.receipt.ReceiptCaptureTest.getActivity(ReceiptCaptureTest.java:43) 

Per una migliore leggibilità, questo è il messaggio di errore sul RuntimeException come una citazione:

Impossibile avviare intenti intento {FLG = 0x14000000 cmp = com.cookbrite.dev/com.cookbrite.ui.ReceiptCaptureActivity (ha extra)} entro 45 secondi. Forse il thread principale non è andato in idle entro un ragionevole lasso di tempo? Potrebbe esserci un'animazione o qualcosa che costantemente ridisegna lo schermo. O l'attività sta facendo chiamate di rete alla creazione? Vedi i log del threaddump. Per il tuo riferimento l'ultima volta che la coda degli eventi era inattiva prima della richiesta di attività richiesta era 1434471981236 e ora l'ultima volta in cui la coda era inattiva era: 1434471981236. Se questi numeri sono uguali, la tua attività potrebbe essere fare la coda degli eventi.

I nostri test esistenti utilizzano Robotium. Un tentativo di scrivere lo stesso test usando Espresso ha prodotto un errore simile, probabilmente dovuto all'anteprima della fotocamera che aggiorna costantemente l'interfaccia utente. Tuttavia, anche con l'anteprima impostata su INVISIBLE, ci imbattiamo ancora in questo problema con Espresso.

Eventuali suggerimenti/suggerimenti su come risolvere questo problema (oltre a tornare a InstrumentationTestRunner)?

+0

il test del robotio funziona correttamente quando l'anteprima è impostata su INVISIBLE o GONE – user2511882

+0

i miei test Robotium continuano a fallire con la stessa RuntimeException quando la revisione è impostata su INVISIBLE. – Yenchi

+0

ok .. l'abbiamo sperimentato prima ... nel nostro caso è stato perché avevamo l'abitudine di lanciare nuove attività su ogni clic del pulsante .. e di conseguenza roboitum si spegneva .. dovevamo uccidere tutte le attività nel tearDown .. – user2511882

risposta

0

Alla fine, cambiamo l'interfaccia utente per ritardare di anteprima della fotocamera di avvio in modo MonitoringInstrumentation non arrabbiarsi con tutto l'aggiornamento dell'interfaccia utente. Inoltre, sia l'interfaccia utente SurfaceView che la TextureView vengono aggiornate non appena viene collegata una videocamera, anche nello stato INVISIBLE o GONE. Questo è il motivo per cui MonitoringInstrumentation si arrende nel nostro caso.

Se si dispone di un test che inizia con un aggiornamento dell'interfaccia utente costante, è consigliabile prendere in considerazione l'interruzione dell'azione fino a startActivitySync() e ottenere un risultato non nullo da getActivity().

0

L'errore in uscita indica che la classe di test si estende ActivityInstrumentationTestCase2. Non sono sicuro che passare al nuovo ActivityTestRule farebbe alcuna differenza nel tuo caso, ma vale la pena di fare un controllo veloce. Mettendo questo in una risposta piuttosto che un commento al fine di includere il codice di esempio:

@RunWith(AndroidJUnit4.class) 
public class ReceiptCaptureTestNew { 
    private ReceiptCaptureActivity mReceiptCaptureActivity; 

    @Rule 
    public ActivityTestRule<mReceiptCaptureActivity> mActivityRule = 
      new ActivityTestRule<>(mReceiptCaptureActivity.class); 

    @Before 
    public void setUp() throws Exception { 
     mReceiptCaptureActivity = mActivityRule.getActivity(); 
    } 

    @After 
    public void tearDown() throws Exception { 
     // Call finish() on all activities in @After to avoid exceptions in 
     // later calls to getActivity() in subsequent tests 
     mReceiptCaptureActivity.finish(); 
    } 

    @Test 
    public void testPreconditions() { 
     assertNotNull(mReceiptCaptureActivity); 
     assertThat(mReceiptCaptureActivity.hasWindowFocus(), is(true)); 
    } 
} 
+0

Sfortunatamente quando scrivo lo stesso test in Espresso, ho usato ActivityRule + Junit4Runner e ho ottenuto lo stesso risultato. Ma grazie per la risposta! – Yenchi