Concetti fondamentali sul test di app Android

Questa pagina illustra i principi fondamentali del test delle app per Android, incluse le migliori pratiche 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 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. 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 del rendimento: lo fa 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 piccola parte dell'app, ad esempio un metodo o una classe.
  • I test end-to-end o grandi test verificano contemporaneamente parti più grandi dell'app, ad esempio un'intera schermata o il 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.

Confronto tra test strumentati e 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 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 ampio: puoi utilizzare un simulatore Android eseguito in locale, 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 instrumentata 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()))

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 ti consente di testare facilmente parti diverse in isolamento. 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 gli stati possibili 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 un'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, ad esempio 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 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 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.