Concetti fondamentali sul test di app Android

Questa pagina illustra i principi fondamentali del test delle app per Android, incluse le best practice principali e i relativi vantaggi.

Vantaggi dei test

I test sono parte integrante del processo di sviluppo dell'app. Eseguendo test costanti sulla tua app, puoi verificarne la correttezza, il comportamento funzionale e l'usabilità prima di rilasciarla pubblicamente.

Puoi testare manualmente la tua app navigando al suo interno. Potresti utilizzare diversi dispositivi ed emulatori, cambiare la lingua di sistema e provare a generare ogni errore utente o a percorrere ogni flusso utente.

Tuttavia, i test manuali non sono scalabili e può essere facile trascurare le regressioni nel comportamento della tua app. I test automatici prevedono l'utilizzo di strumenti che eseguono i test per te, il che è più veloce, più ripetibile e in genere fornisce feedback più utili sulla tua app nelle prime fasi del processo di sviluppo.

Tipi di test in Android

Le applicazioni mobile sono complesse e devono funzionare bene in molti ambienti. Pertanto, esistono molti tipi di test.

Oggetto

Ad esempio, esistono diversi tipi di test a seconda del soggetto:

  • Test di funzionalità: la mia app fa ciò che dovrebbe?
  • Test delle prestazioni: esegue il test in modo rapido ed efficiente?
  • Test di accessibilità: funziona bene con i servizi di accessibilità?
  • Test di compatibilità: funziona bene su ogni dispositivo e livello API?

Ambito

I test variano anche in base alle dimensioni o al grado di isolamento:

  • I test delle unità o i piccoli test verificano solo una parte molto piccola dell'app, come un metodo o una classe.
  • I test end-to-end o test di grandi dimensioni verificano contemporaneamente parti più grandi dell'app, ad esempio un intero schermo o la procedura.
  • I test medi si trovano nel mezzo e verificano l'integrazione tra due o più unità.
I test possono essere piccoli, medi o grandi.
Figura 1: test degli ambiti in un'applicazione tipica.

Esistono molti modi per classificare i test. Tuttavia, la distinzione più importante per gli sviluppatori di app è dove vengono eseguiti i test.

Test con strumenti e test locali

Puoi eseguire test su un dispositivo Android o su un altro computer:

  • I test con strumenti vengono eseguiti su un dispositivo Android, fisico o virtuale. L'app viene creata e installata insieme a un'app di test che inserisce comandi e legge lo stato. I test con strumenti sono in genere test dell'interfaccia utente, che lanciano un'app e poi interagiscono con essa.
  • I test locali vengono eseguiti sulla macchina di sviluppo o su un server, pertanto sono chiamati anche test lato host. Di solito sono piccoli e veloci e isolano il soggetto sottoposto a test dal resto dell'app.
I test possono essere eseguiti come test con strumenti su un dispositivo o come test locali sulla tua macchina di sviluppo.
Figura 2: diversi tipi di test a seconda di dove vengono eseguiti.

Non tutti i test di unità sono locali e non tutti i test end-to-end vengono eseguiti su un dispositivo. Per esempio:

  • Test locale di grandi dimensioni: puoi utilizzare un simulatore Android che viene eseguito localmente, ad esempio Robolectric.
  • Piccolo test con strumenti: puoi verificare che il codice funzioni correttamente con una funzionalità del framework, ad esempio un database SQLite. Puoi eseguire questo test su più dispositivi per verificare l'integrazione con più versioni di SQLite.

Esempi

I seguenti snippet mostrano come interagire con l'interfaccia utente in un test dell'interfaccia utente con strumenti che fa clic su un elemento e verifica che ne venga visualizzato altro.

espresso

// When the Continue button is clicked
onView(withText("Continue"))
    .perform(click())

// Then the Welcome screen is displayed
onView(withText("Welcome"))
    .check(matches(isDisplayed()))

Interfaccia utente di Componi

// When the Continue button is clicked
composeTestRule.onNodeWithText("Continue").performClick()

// Then the Welcome screen is displayed
composeTestRule.onNodeWithText("Welcome").assertIsDisplayed()

Questo snippet mostra parte di un test di unità per un ViewModel (test locale lato host):

// Given an instance of MyViewModel
val viewModel = MyViewModel(myFakeDataRepository)

// When data is loaded
viewModel.loadData()

// Then it should be exposing data
assertTrue(viewModel.data != null)

Architettura verificabile

Con un'architettura dell'app testabile, il codice segue una struttura che consente di testare facilmente diverse parti in modo isolato. Le architetture verificabili hanno altri vantaggi, come una maggiore leggibilità, manutenibilità, scalabilità e riutilizzabilità.

Un'architettura non testabile genera quanto segue:

  • Test più grandi, più lenti e più incostanti. Le classi che non possono essere testate a livello di unità potrebbero dover essere coperte da test di integrazione o UI più grandi.
  • Meno opportunità per testare diversi scenari. I test più grandi sono più lenti, quindi testare tutti i possibili stati di un'app potrebbe non essere realistico.

Per saperne di più sulle linee guida sull'architettura, consulta la guida all'architettura delle app.

Approcci al disaccoppiamento

Se riesci a estrarre parte di una funzione, di una classe o di un modulo dal resto, il test è più facile ed efficace. Questa pratica è nota come disaccoppiamento ed è il concetto più importante per l'architettura testabile.

Le tecniche di disaccoppiamento più comuni sono le seguenti:

  • Suddividi un'app in livelli, come Presentazione, Dominio e Dati. Puoi anche suddividere un'app in moduli, uno per funzionalità.
  • Evita di aggiungere logica a entità con dipendenze elevate, come attività e frammenti. Utilizza queste classi come punti di contatto con il framework e sposta la UI e la logica di business altrove, ad esempio in un livello Composable, ViewModel o di dominio.
  • Evita le dipendenze del framework dirette nelle classi contenenti la logica di business. Ad esempio, non utilizzare i contesti Android in ViewModels.
  • Rendi le dipendenze facili da sostituire. Ad esempio, utilizza interfacce anziché implementazioni concrete. Utilizza Dependency Injection anche se non utilizzi un framework DI.

Passaggi successivi

Ora che sai perché dovresti eseguire test e quali sono i due tipi principali di test, puoi leggere l'articolo Che cosa testare o scoprire di più sulle strategie di test.

In alternativa, se vuoi creare il tuo primo test e imparare facendo, consulta i codelab di test.