Risorse inattive per caffè espresso

Una risorsa di inattività rappresenta un'operazione asincrona i cui risultati influenzano le operazioni successive in un test della UI. Registrando le risorse inattive con Espresso, puoi convalidare queste operazioni asincrone in modo più affidabile quando la tua app.

Identifica quando sono necessarie risorse inattive

Il caffè espresso offre una serie sofisticata funzionalità di sincronizzazione. Questo caratteristica del framework, tuttavia, si applica solo alle operazioni che pubblicano in MessageQueue, ad esempio una sottoclasse di View che disegna i suoi contenuti sullo schermo.

Espresso non è a conoscenza di altre operazioni asincrone, tra cui: a quelli in esecuzione su un thread in background, Espresso non può garantiti in queste situazioni. Per far conoscere a Espresso le per le operazioni a lunga esecuzione, devi registrarle ciascuna come risorsa inattiva.

Se non utilizzi risorse inattive per testare i risultati della tua app asincrone, potresti dover utilizzare uno dei seguenti soluzioni alternative non corrette per migliorare i test affidabilità:

  • Aggiunta di chiamate a Thread.sleep(). Quando ritardi artificiali nei test, i tempi necessari per la suite di test termina l'esecuzione e a volte i test potrebbero non riuscire comunque se eseguiti dispositivi più lenti. Inoltre, questi ritardi non si adattano bene, perché la tua app potrebbe dover eseguire operazioni asincrone più dispendiose in termini di tempo in una versione futura.
  • Implementazione di wrapper nuovi per i nuovi tentativi, che utilizzano un loop per verificare ripetutamente se la tua app continua a eseguire un lavoro asincrono fino a quando non si verifica un timeout. Anche se specifichi un numero massimo di nuovi tentativi nei tuoi test, ogni nuova esecuzione consuma di sistema, in particolare la CPU.
  • Utilizzando le istanze di CountDownLatch, che consentire a uno o più thread di attendere che un numero specifico di operazioni venga eseguite in un altro thread. Questi oggetti richiedono di specificare durata del timeout; altrimenti la tua app potrebbe essere bloccata a tempo indeterminato. I fermi aggiungeranno inoltre complessità superflua al codice, rendendo più difficile la manutenzione.

Espresso consente di rimuovere dai test queste soluzioni alternative inaffidabili puoi invece registrare il lavoro asincrono dell'app come risorse inattive.

Casi d'uso comuni

Quando nei tuoi test vengono eseguite operazioni simili ai seguenti esempi, valuta la possibilità di utilizzare una risorsa inattiva:

  • Caricamento di dati da internet o da un'origine dati locale.
  • Creazione di connessioni con database e callback.
  • Gestione dei servizi tramite un servizio di sistema o un'istanza di IntentService.
  • Esecuzione di una logica di business complessa, come trasformazioni bitmap.

È particolarmente importante registrare le risorse inattive quando queste operazioni aggiornare una UI che verranno convalidate dai test.

Esempi di implementazioni di risorse inattive

Nell'elenco che segue vengono descritti diversi esempi di implementazioni di risorse inattive che puoi integrare nella tua app:

CountingIdlingResource
Mantiene un contatore delle attività attive. Quando il contatore è pari a zero, l'oggetto associato la risorsa è considerata inattiva. Questa funzionalità è molto simile a quella di una Semaphore. Nella maggior parte dei casi, questa implementazione sono sufficienti per gestire il lavoro asincrono della tua app durante i test.
UriIdlingResource
Simile a CountingIdlingResource, ma il contatore deve essere pari a zero per un periodo di tempo specifico prima la risorsa è considerata inattiva. Questo periodo di attesa aggiuntivo richiede per le richieste di rete, per cui un'app nel thread potrebbe subito dopo aver ricevuto una risposta a una precedente richiesta.
IdlingThreadPoolExecutor
Un'implementazione personalizzata di ThreadPoolExecutor che tiene traccia del numero totale di attività in esecuzione all'interno del thread creato piscine. Questo corso utilizza un Da CountingIdlingResource a il contatore delle attività attive.
IdlingScheduledThreadPoolExecutor
Un'implementazione personalizzata ScheduledThreadPoolExecutor. Offre lo stesso di funzionalità come IdlingThreadPoolExecutor per il corso, ma può anche tenere traccia delle attività pianificate per il futuro sono pianificati per essere eseguiti periodicamente.
di Gemini Advanced.
.

Crea la tua risorsa inattiva

Quando utilizzi le risorse inattive nei test della tua app, potresti dover fornire gestione o logging delle risorse personalizzate. In questi casi, le implementazioni elencati nella sezione precedente potrebbero non essere sufficienti. In questo caso, puoi estendi una di queste implementazioni di risorse inattive o creane una personalizzata.

Se implementi la tua funzionalità di risorsa inattiva, mantieni quanto segue soprattutto la prima:

Richiamare le transizioni allo stato di inattività al di fuori dei controlli di inattività.
Quando l'app diventa inattiva, chiama onTransitionToIdle() al di fuori di eventuali implementazioni isIdleNow(). In questo modo Espresso non compie un secondo, verifica inutile per determinare se un dato la risorsa inattiva è inattiva.

Il seguente snippet di codice illustra questo consiglio:

Kotlin

fun isIdle() {
    // DON'T call callback.onTransitionToIdle() here!
}

fun backgroundWorkDone() {
    // Background work finished.
    callback.onTransitionToIdle() // Good. Tells Espresso that the app is idle.

    // Don't do any post-processing work beyond this point. Espresso now
    // considers your app to be idle and moves on to the next test action.
}

Java

public void isIdle() {
    // DON'T call callback.onTransitionToIdle() here!
}

public void backgroundWorkDone() {
    // Background work finished.
    callback.onTransitionToIdle() // Good. Tells Espresso that the app is idle.

    // Don't do any post-processing work beyond this point. Espresso now
    // considers your app to be idle and moves on to the next test action.
}
Registra le risorse inattive prima di averne bisogno.

I vantaggi della sincronizzazione associati alle risorse inattive hanno effetto solo dopo la prima chiamata di Espresso al isIdleNow().

Il seguente elenco mostra diversi esempi di questa proprietà:

  • Se registri una risorsa inattiva in un metodo annotato con @Before, la risorsa inattiva diventa effettiva nella prima riga di ogni test.
  • Se registri una risorsa inattiva all'interno di un test, la risorsa inattiva diventa effettiva durante la prossima azione basata su Espresso. Questo comportamento si verifica anche se l'azione successiva è nello stesso test dell'istruzione Registra la risorsa inattiva.
Annulla la registrazione delle risorse inattive dopo aver finito di utilizzarle.

Per risparmiare risorse di sistema, devi annullare la registrazione delle risorse inattive appena perché non ti servono più. Ad esempio, se registri una risorsa inattiva in un metodo annotato con @Before, è meglio annullare la registrazione di questa risorsa in metodo corrispondente annotato con @After.

Utilizza un registro di inattività per registrare e annullare la registrazione delle risorse inattive.

Se utilizzi questo container per le risorse inattive della tua app, puoi registrare e annullare ripetutamente la registrazione delle risorse inattive secondo necessità e osservare comunque comportamento degli utenti.

Gestisci solo lo stato semplice dell'app nelle risorse inattive.

Ad esempio, le risorse inattive implementate e registrate non devono contenere riferimenti a View oggetti.

Registra risorse inattive

Espresso fornisce una classe container in cui puoi inserire il tempo di inattività dell'app Google Cloud. Questa classe, chiamata IdlingRegistry è un artefatto autonomo che riduce l'overhead minimo per la tua app. Il corso ti consente anche di seguire i passaggi indicati di seguito per migliorare il rendimento manutenibilità:

  • Crea un riferimento a IdlingRegistry, anziché alle risorse inattive contenuti nei test dell'app.
  • Mantieni le differenze nella raccolta delle risorse inattive che utilizzi per ciascuna variante della build.
  • Definisci le risorse inattive nei servizi dell'app, anziché nella UI che fanno riferimento a questi servizi.
di Gemini Advanced.

Integra le risorse inattive nella tua app

Sebbene sia possibile aggiungere risorse inattive a un'app in diversi modi, in particolare mantiene l'incapsulamento dell'app, consentendo devi specificare una particolare operazione rappresentata da una determinata risorsa inattiva.

Quando aggiungi risorse inattive nella tua app, ti consigliamo vivamente di posizionare della logica della risorsa inattiva nell'app stessa ed eseguire solo la registrazione e operazioni di annullamento della registrazione nei test.

Anche se si crea una situazione insolita di utilizzare un'interfaccia di solo test in di produzione seguendo questo approccio, puoi aggregare le risorse inattive il codice già in tuo possesso, mantenendo le dimensioni dell'APK e il conteggio dei metodi dell'app.

Approcci alternativi

Se preferisci non avere una logica per le risorse inattive nella produzione dell'app di Google Cloud, esistono altre strategie di integrazione attuabili:

  • Creare varianti di build, ad esempio quella di Gradle prodotto versioni e usare risorse inattive solo nella build di debug della tua app.
  • Usa un framework di inserimento delle dipendenze come Dagger per inserire lo stato inattivo dell'app delle dipendenze dalle risorse nei test. Se utilizzi Dagger 2, l'iniezione stessa deve avere origine da un sottocomponente.
  • Implementa una risorsa inattiva nei test dell'app ed esponi la parte dell'implementazione della tua app che devono essere sincronizzate in quelle test.

    Attenzione : anche se questa decisione di progettazione sembra creare un riferimento autonomo alle risorse inattive, interrompe anche incapsulamento in tutte le app tranne la più semplice.

Risorse aggiuntive

Per ulteriori informazioni sull'uso di Espresso nei test Android, consulta le seguenti risorse.

Campioni