Differenza tra Mock, Content provider, Broadcast receiver, Service e Activity

Differenza tra Mock, Content provider, Broadcast receiver, Service e Activity

Mock

I mock sono degli oggetti creati per imitare componenti reali del software. Gli scopi principali del loro utilizzo sono:

  • Consentire lo sviluppo di componenti software anche in assenza di componenti necessari al loro funzionamento (spesso sviluppati parallelamente).
  • Permettere di isolare i componenti sotto test dal resto del software e quindi, di eseguire i test in modo indipendente e ripetibile.

Pertanto, il comportamento di un oggetto complesso può essere simulato da un mock, consentendo al programmatore di scoprire se l’oggetto sotto test risponde correttamente al variare degli stati del mock.

Se un oggetto (reale) ha le seguenti caratteristiche è indicato usare dei mock per il testing di tali componenti:

  • Fornisce risultati non deterministici (ad esempio misurazione della temperatura).
  • Ha stati difficili da creare o riprodurre.
  • È lento.
  • Non è stato ancora sviluppato.

I mock devono inoltre condividere le interfacce dei componenti reali, in modo che i componenti che li utilizzano non debbano essere adattati a seconda di quali oggetti devono usare.

Test Unitari

Nella programmazione, un Test unitario è un sistema con cui singole unità di codice, uno o più moduli congiuntamente con i propri dati, procedure di utilizzo e procedure operative, sono sottoposti a test per determinare se sono idonei per l’uso.

Intuitivamente, si può immaginare un’unità come la più piccola parte verificabile di un’applicazione. Nella programmazione procedurale un’unità può essere un intero modulo, ma è più comunemente una singola funzione o una procedura. Nella programmazione orientata agli oggetti un’unità è spesso un intera classe, ma potrebbe essere anche un singolo metodo. Gli Unit test sono test del software “scritti da programmatori, per programmatori, in un linguaggio di programmazione”. Questi dovrebbero isolare il componente da testare e rendere possibile la ripetizione del test innumerevoli volte. Motivo per cui, in genere, unit test e mock vengono sviluppati congiuntamente e disposti negli stessi package.

Si immagini di dover sviluppare uno unit test che debba fare una prova di cancellazione. Se il test eliminasse realmente i dati presenti nella base dati o nel filesystem, ci sarebbero problemi nella ripetizione del test, questo rende necessario l’uso di un mock per evitare la modifica permanentemente dei dati presenti sul dispositivo.

Focalizzando i test unitari, nell’ambito della programmazione di App Android, bisogna, in prima istanza, rispondere a tre domande:

  • Cosa bisogna testare in una App Android?
  • Qual è la strategia di test con maggior efficacia?
  • Come si possono automatizzate gli unit test?

D’altro canto, in una App Android coesistono, sia componenti nativi del SO Android, sia comuni classi Java. I test non devono soffermarsi solo su uno dei tipi appena descritti, ma devono ricercare bug in tutto il codice sviluppato. Da ciò la necessità di Framework di test che permettano di testare tutti i tipi di componenti, siano essi nativi Android o semplici classi Java.

Per quanto riguarda la strategia da adottare è possibile utilizzare tutte e tre le strategie di test (Bottom-Up, Top-Down, Sandwitch), resta fondamentale però prestare le dovute attenzioni agli eventi ed ai cicli di vita dei componenti nativi del Framework Android.

Infine, la possibilità di automatizzare i test dipende dal Framework di test utilizzato, infatti, a seconda della scelta si possono automatizzare i test di singoli componenti, così come, creare delle vere e proprie Suite di test per l’esecuzione automatica di innumerevoli test su svariati componenti.

Differenza tra Mock, Content provider, Broadcast receiver, Service e Activity

Test di integrazione

I test di integrazione sono disegnati per testare il comportamento di componenti che lavorano congiuntamente tra loro. Si eseguono quindi dei test integrando moduli che hanno passato i Test unitari.

In generale, per testare una Activity è necessario integrarla con svariati componenti del sistema, come il Manager dell’Activity, che deve regolare il corretto funzionamento del ciclo di vita, l’accesso alle risorse ed ai dati. Quindi, bisogna che l’ambiente di test fornisca tutti gli strumenti per permettere ciò.

Analogo ragionamento và fatto per altri componenti quali Service, Content provider e Broadcast Receiver.

In tutti questi casi il Framework di test adottato deve cercare, per quanto possibile, di semplificare i processi di scrittura di questi test, che risulta, in genere, lungo e tedioso, ma assolutamente necessario per lo sviluppo di codice di qualità.

Le strategie adottate in questi test, in genere, sono tre:

  1. Bottom-Up: testa partendo dai componenti a basso livello, per arrivare poi ai componenti di alto livello.
  2. Top-Down: parte dai componenti di alto livello per arrivare ai componenti di basso livello.
  3. Sandwitch: si cerca la giusta via di mezzo tra i due sistemi sopra citati.

Si definisce un componente di basso livello, un componente software che non ha dipendenze da altri componenti software all’interno di una applicazione. Al contrario, un componente di alto livello è un componente che ha dipendenze da altri componenti software all’interno dell’applicazione stessa.

Ulteriori classificazioni possono essere fatte nella relazione tra componenti software, una delle più importanti per i test di integrazione è:

  1. statica
  2. dinamica

La prima relazione è la più semplici da individuare, infatti, detto tipo di relazioni sono dichiarate all’interno del file Manifest.xml . Quelle dinamiche, invece, dipendono dall’accoppiamento tra classi java, conseguentemente, serve una conoscenza approfondita del codice prodotto per poter comprendere a pieno detto accoppiamento.

In genere si sviluppano due tipi di App:

  1. Server Client
  2. Client

Nelle App Server Client, generalmente, i primi test vengono effettuati sull’applicazione lato client. Solo in un secondo momento si passa ai test lato server. Facendo in questo modo si riesce ad evitare che bug presenti lato Server, si ripercuotano sul lato Client del progetto. Questo problema, non è presente invece nel caso di App Client site, infatti, non dipendendo queste da software Server site, il tester è libero di testare l’App senza doversi preoccupare, che, ulteriori componenti software vadano ad influenzare i test sviluppati.

A valle delle classificazioni appena esposte analizziamo i vari componenti Android a che livello si trovano (alto o basso livello):

  • Content Provider: questo componente ha il compito di fornire dati a chi ne fà richiesta, quindi, non dovrebbe dipendere da altri componenti che non siano le Application Programming Interface (API) di accesso ai dati fisici di Android. Quindi, questo componente, nella maggior parte dei casi, è da considerarsi di basso livello.
  • Broadcast receiver: anche questo componente, come il Content provider dovrebbe dipendere dalle sole API del SO, dato che il suo compito principale è quello di raccogliere i messaggi di sistema (Intent) per poi notificarlo ad altri componenti all’interno dell’App, per cui, anche in questo caso, nella maggio parte dei casi, questo è un componente di basso livello.
  • Service: con questo componente non si può più parlare di basso livello, dato che, in genere, i Service hanno bisogno, per il loro funzionamento, di interfacciarsi con altri componenti, come Content Provider e Broadcast receiver.
  • Activity: questo, generalmente è il componente di alto livello dell’App, infatti, è consuetudine che l’Activity dipenda da altri componenti, come Service, Content Provider e Broadcast receiver.

UI test

È molto importante testare il corretto funzionamento della UI, questo infatti, permetterà di trovare errori che potrebbero risultare bloccanti per l’utilizzo di una App. Bisogna prestare particolare attenzione per i test che controllano il corretto funzionamento dei componenti dell’interfaccia utente. Infatti, l’interfaccia utente di una App, può essere modificata solo dal thread principale.

Test di sistema

IEEE definisce il test di sistema come “il test condotto su un sistema completo e integrato per valutare la conformità del sistema con le specifiche funzionali“. Il test del sistema verifica la conformità dei requisiti funzionali e non funzionali ed ha lo scopo di scoprire errori, a questo livello di test, probabilmente causati dal dispositivo o dall’ambiente di esecuzione reale dell’App.

La grande varietà di dispositivi mobili presenti sul mercato e di conseguenza, la quantità di hardware con cui una App può dover interagire è praticamente illimitata. Questo rende la fase dei test di sistema un processo molto complesso, contando che è praticamente impossibile testare l’App con tutti i dispositivi presenti in commercio. In generale, i tester devono eseguire le applicazioni su una serie di dispositivi diversi, ognuno con varie limitazioni di risorse. Un test di sistema, procede, generalmente, per stadi successivi, in modo, da meglio controllare la risposta dell’App alle caratteristiche dei dispositivi.

I Test di sistema procedono di solito in tre fasi:

  • Simulazione: in questa fase il test è eseguito completamente in ambiente simulato.
  • Prototipazione: in questa fase, le componenti reali vanno a sostituire gradualmente i componenti emulati, ma il processore continua ad essere simulato.
  • Pre-produzione: infine, viene sostituito anche il processore emulato, con un processore reale.

Diversi livelli di sforzo, costi e tempi caratterizzano ogni fase. Per esempio, la fase di simulazione è facile e poco costosa, mentre i test in fase di pre-produzione possono risultare molto costosi.

Continuous Integration

La Continuous Integration (CI) è una pratica di sviluppo software in cui i membri di un team integrano frequentemente il loro lavoro (generalmente usando sistemi di versioning). Ogni integrazione è verificata da un build, che riscontra se vi siano problemi di compilazione. Spesso vengono usati strumenti quali jenkins o hudson, che permettono la creazione di un insieme di step da eseguire. Tra le operazioni eseguite in fase di integrazione c’è anche l’esecuzione di test che evidenzino errori di integrazione o di regression.

Pubblicato da Vito Lavecchia

Lavecchia Vito Ingegnere Informatico (Politecnico di Bari) Email: [email protected] Sito Web: https://vitolavecchia.altervista.org

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *