L’utilizzo di unit test per testare il funzionamento corretto di singoli blocchi di codice è una delle pratiche di ingegneria del software più ampiamente accettate ed utilizzate.

Nel caso di dispositivi IoT embedded, spesso non si dedica il tempo necessario allo sviluppo di unit test solidi poiché l’interfaccia anche con la parte hardware rende più difficile la creazione di unit test rispetto a dispositivi formati solo da software.

Questo non è vero nel caso di Zerynth, che ha sviluppato un workbench di test automatici che permettono il rilascio e test di una nuova versione in modo rapido e affidabile.

Unit tests

Una delle pratiche di ingegneria del software più utilizzate ed accettate è quella di scrivere ed utilizzare dei unit tests, ovvero singole sottounità di un codice per assicurarsi che ognuna di esse abbia il comportamento atteso nei suoi possibili casi d’uso.

Generalmente si tratta di pratiche automatizzate che permettono con il solo investimento di tempo per la stesura dei  i test richiesti, di migliorare di molto la qualità del codice e di trovare eventuali comportamenti anomali durante i test, velocizzando  i tempi di rilascio nel caso i test vengano utilizzati.

La necessità di una code base solida e priva di errori è particolarmente importante nel caso di dispositivi embedded, in quanto questi, a differenza di soluzioni solo software facilmente aggiornabili con nuove release, possono risultare difficilmente aggiornabili o addirittura difficilmente raggiungibili una volta installati. Per questo motivo, è fondamentale sviluppare unite test adatti e specifici per ciascun dispositivo embedded

Purtroppo questo non avviene spesso, in quanto testare un dispositivo embedded richiede più tempo e risorse di un semplice software o di una web-app. In particolare, unit test embedded possono richiedere la costruzione di un setup di test, specifico per ogni unità, e possono dover essere adattati a diversi tipi di dispositivo.

Va da se, che dover testare centinaia di funzioni su un intero array di dispositivi diversi, costruendo un setup adatto e assicurarsi che questo non presenti errori sistematici, non sia un’impresa semplice, che richiede un investimento di tempo e risorse non indifferente, motivo per cui molti sviluppatori embedded scelgono di non sviluppare e mantenere un workbench di test.

Ciò nonostante, la piattaforma IoT di Zerynth è stata sviluppata in modo tale che tutte le risorse investite nello sviluppo di unit test embedded siano fondamentali per assicurare alla nostra utenza un prodotto rifinito ed affidabile.  Per questo motivo, la pipeline di test prevede che tutte le unità di codice delle nuove funzionalità da implementare vengano prima testate su tutte le board montate su workbench (db zm1, 4zerobox etc) e poi rilasciate, se superano il test su ognuno dei nostri dispositivi.

La pipeline di test di Zerynth

Il rilascio di codice di basso livello e librerie in Zerynth segue un processo di questo  tipo:

  1. sviluppo del codice;
  2. scrittura del relativo unit test;
  3. lancio della catena automatica di unit test;
    1. debug nel caso emergano comportamenti anomali;
    2. Ripetere da punto 3);
  4. rilascio di nuova versione del SDK.

dispositivi embedded

Figura 1.Pipeline di test di Zerynth

Il workbench di Zerynth supporta vari tipi di test.

Unit test rapidi. Questi test sono lanciati prima di ogni rilascio, controllano il comportamento di ogni unità di codice, riportando comportamenti anomali che verranno quindi corretti prima del rilascio. Questi test vengono lanciati automaticamente su ogni scheda supportata testando ogni libreria disponibile e vengono aggiornati periodicamente per assicurare una copertura dei test completa. Una volta lanciati, i test girano in maniera autonoma, fino al raggiungere i risultati finali in output. Rientrano in questo tipo di unit test tutti quelli che coprono i driver delle diverse periferiche (ADC, I2C, SPI, USART …) e sensoristica.

Unit test di stabilità. Questi test operano in maniera continua nel tempo  e puntano a verificare la stabilità della codebase nel tempo. I test di stabilità pubblicano il loro stato nel cloud per permetterci tenere traccia di eventuali errori che risulterebbero difficili da identificare su unit test con durata limitata. Tra questi rientrano, per esempio, test di log dati su flash, per verificare casi di possibili corruzioni  di memoria che possono verificarsi dopo molti cicli di scrittura e lettura. Un’altra casistica, invece riguarda i test di stabilità di connettività e invio dati sul cloud, effettuati in accoppiata con un disturbatore di rete per simulare condizioni di rete critiche.

FOTA. Infine, vengono effettuati prima di ogni release test di affidabilità del FOTA, per assicurarsi che per ogni device si possa sempre aggiornare il firmware ad ogni release.

dispositivi embedded

Figura 2. Test di benchwork rapidi e di stabilità

dispositivi embedded

Figura 3. Test benchwork di stabilità

L’investimento nello sviluppo di unit test, nonostante le difficoltà dell’embedded dà i suoi frutti, permettendo quindi di testare in maniera completa, rapida e continuativa il codice e di rilasciare quindi nuove e solide feature embedded con rapidità.

Un esempio pratico di unit test

dispositivi embedded

Figura 4. Esempio di Unit Test per gpio

In conclusione, in Figura 4, un semplice esempio di unit test per testare il corretto funzionamento di interrupt callbacks pensato per le board ZM1-DB e 4ZeroBox-Mobile. Il test utilizza un primo pin sulla scheda per innescare la chiamata di una callback inizializzata su un secondo pin. Questa callback invia un output verso il workbench, che confronta l’output con quello atteso per decretare il risultato del test.

Nello specifico:

  • Righe 10-13: inizializzazione del  pin di output
  • Riga 16: definizione della callback
  • Righe 20-21: inizializzazione inizializzazione del pin di input a cui associamo la callback

Righe 22-42: il pin di output viene fatto muovere per innescare la callback di test.

Per scoprire tutte le funzionalità supportate e testate sui nostri dispositivi IoT visita la documentazione.

Share This Story, Choose Your Platform!

About the Author: Elia Guglielmin

Elia è un Embedded Software Engineer a Zerynth, ha una laurea in Fisica sperimentale all’Università di Padova. I suoi interessi principali sono le applicazioni con Real Time Operative Systems (RTOS) su dispositivi embedded e automazione con l’utilizzo di questi. Nel tempo libero suona il basso elettrico e porta il gatto al parco al guinzaglio.

Follow Zerynth on

Latest Posts