I test per lo sviluppo software

L'importanza dei test nello sviluppo software e i possibili approcci.

Nel paragrafo precedente è stato spiegato il meccanismo di passaggio tra gli ambienti e si è detto che la promozione del software è vincolata al superamento di test. Tali test sono suddivisi in più tipologie, per caratteristiche e scopo. Non c’è alcuna regola scritta per indicare quali test effettuare per ogni passaggio, come sempre dipende molto dal tipo di progetto, dalla sua criticità e dalla gestione dello stesso. In molti casi i test non sono formalizzati, ma ci si basa sul responso di qualcuno, quindi si rientra nel caso “User acceptance test”. Di seguito l’elenco della maggior parte di test attuabili, mentre nei paragrafi successivi saranno esaminati quelli più diffusi:

  • Path testing
  • Data set testing
  • Unit testing
  • System testing
  • Integration testing
  • Black-box testing
  • White-box testing
  • Regression testing
  • Automation testing
  • User acceptance testing
  • Software performance testing

Unit testing

L’intento di questa tipologia di test è la verifica di una determinata unità di codice. Per unità si intende il minimo componente di un programma dotato di funzionamento autonomo; a seconda del paradigma o del linguaggio di programmazione, questo può corrispondere a una singola funzione nella programmazione procedurale, o una singola classe o un singolo metodo nella programmazione a oggetti.

Come per le altre forme di testing, lo unit testing può essere avviato in maniera “manuale” o automatizzata.

Lo scopo dello unit testing è quello di verificare il corretto funzionamento di parti di programma permettendo così una precoce individuazione dei bug. Uno unit testing accurato può dare un’indicazione del corretto funzionamento del software, con importanti vantaggi:

  • Semplifica le modifiche
  • Semplifica l’integrazione
  • Supporta la documentazione
  • Separa l’interfaccia dall’implementazione

 

Semplifica le modifiche

Se si procede scrivendo test case per tutte le funzioni e i metodi, nel momento in cui una modifica produce un fallimento del test, si può facilmente individuare la modifica responsabile e provvedere a risolvere il problema.

L’insieme di test, spesso detta “batteria” costituisce una sorta di certificazione del lavoro svolto. Tuttavia questo è vero solo quando l’insieme dei test prodotti copre una percentuale significativa delle possibili casistiche che possono porsi (code coverage).

 

Semplifica l’integrazione

Lo unit testing semplifica l’integrazione di moduli diversi, magari implementati da persone diverse, perché permette di verificare gli effetti congiunti delle modifiche apportate. Poiché alcune parti di codice possono far riferimento ad altre, succede spesso che gli effetti delle modifiche si propaghino in maniera imprevista e involontaria, generando possibili casi di errore. La presenza degli unit test permette l’individuazione di queste criticità e porta maggiore consapevolezza e visibilità sulle funzionalità previste dal programma.

 

Supporta la documentazione

Lo unit testing fornisce una documentazione intrinseca del codice, perché è per costruzione un set di esempi di utilizzo delle API implementate. Tali esempi indicano l’uso appropriato delle unità di codice e i comportamenti errati che devono essere identificati nel funzionamento dell’applicativo. Sebbene i test da soli non possono costituire la sola documentazione necessaria, costituiscono una forma particolarmente pratica che difficilmente sarebbe descrivibile a parole. Inoltre, la tradizionale documentazione diventa spesso obsoleta a cause di successive modifiche del codice non documentate.

 

Separa l’interfaccia dall’implementazione

Per definizione il test unitario deve coinvolgere unità autonome di codice, il che impone di separare l’interfaccia dall’implementazione, che è di per sé buona prassi. In questo modo si rende il comportamento dell’applicativo indipendente dall’origine dei dati o da condizioni particolari, rendendolo robusto e predisposto al cambiamento.

 

Integration testing

Questa è la fase di test del software in cui i moduli sviluppati dai singoli programmatori sono combinati e testati come gruppo unitario. Gli scopi di questi test sono:

  • Verifica funzionale
  • Prestazioni
  • Affidabilità
  • Verifica del soddisfacimento delle specifiche

Regression testing

Il test di regressione è un tipo di prova del software che cerca di scoprire nuovi bug del software, o regressioni, in ambienti preesistenti e dichiarati funzionanti, introdotti dopo cambiamenti quali:

  • Aggiunta di funzionalità
  •  Patch
  • Cambiamenti di impostazioni

 

L’intento dei test di regressione è quello di garantire che un cambiamento come quelli sopra menzionati non abbia introdotto nuovi difetti.  In pratica, con questa tipologia di test si vuole determinare se un cambiamento in una parte del software agisce sulle altre parti del software preesistenti compromettendone il funzionamento complessivo.

Ad esempio si possono eseguire i test effettuati durante il rilascio precedente, controllando se i difetti corretti nell’aggiornamento precedente sono riemersi. Ovviamente non si può tenere traccia dell’insieme complessivo dei test effettuati su tutti i rilasci dell’applicazione dalla prima pubblicazione; quindi nel corso del tempo si cerca di mantenere un set minimo e appropriato dei test necessari, magari aggiungendo i test relativi ai rilasci più recenti, ad esempio l’ultimo.

Nello sviluppo software l’insorgere di nuove o il riemergere di vecchie defezioni è abbastanza comune. A volte il riemergere di un problema si verifica perché una correzione si perde attraverso pratiche di scarso controllo di revisione, non effettuando un numero sufficiente di test durante lo sviluppo. Spesso, la correzione per un problema è prona ad introdurre nuovi errori, in quanto si tende a risolvere il problema nel caso specifico dove è stato segnalato, senza tenere conto dell’applicazione nel complesso o di logiche di business. Tali casistiche sono alimentate dal turnover sui progetti, e dalla negligenza dello sviluppatore e del committente. Anche se questo passaggio può essere fatto attraverso procedure di test manuale, lanciando a mano i test costruiti e valutandone il risultato, viene spesso realizzato mediante strumenti automatici.  Questi test possono essere effettuati periodicamente, in modo da anticipare i problemi alla promozione del software, oppure in occasione della promozione stessa vincolando la promozione al superamento di tali test.

Automation testing

L’adozione di test di regressione o test di integrazione presenta il vantaggio di evitare l’occorrenza di problemi sull’ambiente di produzione. Poiché una volta costruiti i test, in linea teorica, non c’è bisogno dell’intervento umano per eseguirli, tali test vengono automatizzati. All’aumentare del grado di complessità dei test, l’automazione diventa sempre più difficile da impiegare, ad esempio nel caso di test che coinvolgano l’interfaccia grafica.

Gli strumenti di automazione di test possono essere costosi: alcuni sono open source e gratuiti, ma la configurazione e la manutenzione occupa comunque risorse e quindi costi da sostenere. Solitamente sono impiegati test automatici in combinazione con test manuali, cercando di trovare un compromesso tra costi e benefici.

Ci sono due approcci generali per l’automazione di test:

 

  • Test basati su codice: Interfacce per librerie, moduli o classi vengono testati con una varietà di input che dovrebbero coprire tutte le casistiche possibili, in modo da convalidare che i risultati restituiti siano corretti.
  • Test di interfaccia grafica: Un framework di test simula l’utilizzo dell’interfaccia utente, secondo precise sequenze definite in maniera sistematica. Ad esempio, è possibile indicare quali combinazioni di tasti e click del mouse si devono verificare e il sistema osserva i cambiamenti risultanti nell’interfaccia utente, per convalidare che il comportamento osservabile del programma è corretto.

User acceptance testing

Infine il metodo più semplice e intuitivo è costituito dall’User acceptance test. Tale test consiste nel richiedere l’accettazione del software da parte dell’utente, che validerà il lavoro (in termini di funzionamento e qualità) secondo i criteri che ritiene opportuni. Tale fase è generalmente l’ultima del processo di test, e viene effettuata una volta che i requisiti funzionali sono garantiti. Questo perché l’utente finale spesso ignora tali requisiti e giudica l’applicativo da un punto di vista personale, magari anteponendo le proprie necessità o i propri gusti ad aspetti funzionali imposti dalle specifiche. Tuttavia questo test è importante proprio perché è condotto dall’utilizzatore finale, ovvero permette di validare l’intero processo dimostrando che il problema inizialmente posto ha trovato soluzione tramite il software implementato.

danielefontani

Actually CTO in Sintra Consulting s.r.l, I'm senior developer and architect specialized on portals, intranets, and others business applications. Particularly interested in Agile developing and open source projects, I worked on some of this as project manager and developer. My experience include: Frameworks \Technlogies: .NET Framework (C# & VB), ASP.NET, Java, php, Spring Client languages: XML, HTML, CSS, JavaScript, Angular.js,Angular. jQuery Platforms: Sharepoint,Liferay, Drupal Databases: MSSQL, ORACLE, MYSQL, Postgres

Lascia un commento