Concetti fondamentali sul test di app Android

Questa pagina descrive i principi fondamentali del test delle app per Android, incluse le best practice centrali 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 la tua app manualmente navigando al suo interno. Potresti utilizzare dispositivi ed emulatori diversi, cambiare la lingua del sistema e provare a generare ogni errore utente o attraversare ogni flusso utente.

Tuttavia, i test manuali non sono scalabili e può essere facile trascurare regressioni nel comportamento della tua app. I test automatizzati prevedono l'utilizzo di strumenti che eseguono i test al tuo posto, il che è più veloce, più ripetibile e in genere fornisce feedback più utili sulla tua app in una fase precedente 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 dell'argomento:

  • Test funzionale: la mia app fa quello che dovrebbe fare?
  • Test delle prestazioni: le esegue 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 test di piccole dimensioni verificano solo una parte molto piccola dell'app, ad esempio un metodo o una classe.
  • I test end-to-end o big test verificano contemporaneamente parti più grandi dell'app, ad esempio un'intera schermata o un flusso utente.
  • 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: ambiti di test 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 strumentati e test locali

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

  • I test strumentati vengono eseguiti su un dispositivo Android, fisico o emulato. L'app viene creata e installata insieme a un'app di test che inserisce comandi e legge lo stato. I test strumentati sono in genere test dell'interfaccia utente che avviano 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 in esame dal resto dell'app.
I test possono essere eseguiti come test strumentati su un dispositivo o come test locali sulla macchina di sviluppo.
Figura 2: diversi tipi di test a seconda di dove vengono eseguiti.

Non tutti i test delle 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.
  • Test strumentato di piccole dimensioni: puoi verificare che il tuo codice funzioni bene con una funzionalità del framework, ad esempio un database SQLite. Potresti eseguire questo test su più dispositivi per verificare l'integrazione con più versioni di SQLite.

Esempi

I seguenti snippet mostrano come interagire con la UI in un test UI strumentato che fa clic su un elemento e verifica che un altro elemento venga visualizzato.

espresso

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

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

UI di composizione

// 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 delle 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 testabile

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

Un'architettura non testabile produce quanto segue:

  • Test più grandi, più lenti e più instabili. Le classi che non possono essere testate a livello unitario potrebbero dover essere coperte da test di integrazione o test 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 per l'architettura, consulta la guida all'architettura delle app.

Approcci al disaccoppiamento

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

Le tecniche di disaccoppiamento più comuni includono:

  • Dividi un'app in livelli come Presentazione, Dominio e Dati. Puoi anche dividere un'app in moduli, uno per funzionalità.
  • Evita di aggiungere logica a entità con grandi dipendenze, come attività e fragment. Utilizza queste classi come punti di accesso al framework e sposta la UI e la logica di business altrove, ad esempio in un elemento componibile, un ViewModel o un livello di dominio.
  • Evita le dipendenze dal framework dirette nelle classi contenenti la logica di business. Ad esempio, non utilizzare i contesti Android nei ViewModel.
  • Semplifica la sostituzione delle dipendenze. Ad esempio, utilizza interfacce anziché implementazioni concrete. Utilizza l'inserimento delle dipendenze anche se non utilizzi un framework DI.

Passaggi successivi

Ora che sai perché dovresti eseguire i test e quali sono i due tipi principali, puoi leggere 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.