progetto e realizzazione di un’infrastruttura di test per un sistema pacs

59
  UNIVERSITÀ DEGLI STUDI DI TRIESTE FACOLTÀ DI INGEGNERIA Corso di Laurea specialistica in Ingegneria Informatica Tesi di Laurea in Prorgammazione Web Progetto e realizzazione di un’infrastruttura di test per un sistema PACS Laureando Relatore Giacomo Petronio Prof. Eric Medvet Correlatore Ing. Andrea Poli Anno Accademico 2010-2011

Upload: giacomo-petronio

Post on 16-Jul-2015

568 views

Category:

Documents


0 download

TRANSCRIPT

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

 

UNIVERSITÀ DEGLI STUDI DI TRIESTE 

FACOLTÀ DI INGEGNERIA

Corso di Laurea specialistica in Ingegneria Informatica

Tesi di Laurea in

Prorgammazione Web

Progetto e realizzazione di un’infrastruttura di

test per un sistema PACS

Laureando Relatore

Giacomo Petronio Prof. Eric MedvetCorrelatore

Ing. Andrea Poli

Anno Accademico 2010-2011

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

 

 Alla mia famiglia

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

 

Sommario

Introduzione ................................................................................................................................ 1

Motivazioni .................................................................................................................................. 2

Qualità del software..................................................................................................... 2

Software Testing .......................................................................................................... 2

Testare un PACS ........................................................................................................... 3

Marcatura CE ............................................................................................................... 3

Analisi .......................................................................................................................................... 6

Il sistema O3-DPACS ..................................................................................................... 6

Il processo attuale ........................................................................................................ 8

Teoria dei test ............................................................................................................ 13

Incidenza dei bug nel sistema .................................................................................... 15

Analisi delle classi e package...................................................................................... 17

Database Testing ........................................................................................................ 19

Test funzionali ............................................................................................................ 20

Tecnologie utilizzate .................................................................................................................. 22

JUnit ........................................................................................................................... 22

Classi Stub e Mock (Mockito) ..................................................................................... 24

DBUnit ........................................................................................................................ 27

Dependency Injection ................................................................................................ 27

Sviluppo ..................................................................................................................................... 30

Creazione di unit test ................................................................................................. 30

Database Testing (jdbc, stored procedure, jpa) ......................................................... 35

Creazione dei test di integrazione ed MBean ............................................................ 41

Test dei servizi ............................................................................................................ 44

Automazione ............................................................................................................................. 48

Script di build ed esecuzione automatici ................................................................... 48

Utilizzo di Jenkins ....................................................................................................... 49

Conclusioni ................................................................................................................................ 50

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

 

Risultati ottenuti ........................................................................................................ 50

Confronto ................................................................................................................... 50

Glossario .................................................................................................................................... 51

Bibliografia ................................................................................................................................. 51

Appendice .................................................................................................................................. 52

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

1

Introduzione

Lo scopo di questa tesi è quello di progettare e realizzare un’infrastruttura per migliorare il processo

di creazione ed esecuzione dei test in O3-Enterprise, con particolare attenzione sul programma

software O3-DPACS. Il raggiungimento di questo obbiettivo passa attraverso l’analisi del software

oggetto dei test, l’identificazione dei principali problemi che si vengono ad affrontare in un sistema di

tipo server, la ricerca di soluzioni e di pratiche comuni anche tramite l’utilizzo di strumenti appositi, la

creazione di test ed infine l’automazione della loro esecuzione. L’eventuale miglioramento ottenuto

viene quindi valutato mettendo a confronto il processo di test precedente con quello proposto.

Nota: mi scuso per le innumerevoli occorrenze della parola ‘test’ 

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

2

Motivazioni

Spesso, programmando sia per scopi personali che professionali, ci si ritrova a creare ed effettuaredei test senza porsi particolari domande sulla reale utilità o necessità di impiegare del tempo per

questo tipo di operazioni. Pur sembrando ragionevolmente ovvio che i test debbano essere effettuati

in quanto necessari per verificare il corretto funzionamento dell’applicazione, non è altrettanto

lampante quale sia la giusta quantità di test a cui sottoporre il software. Si ritiene quindi lecito

interrogarsi su quante risorse sia opportuno impiegare nella fase di test, e se l’investimento avrà un

reale ritorno e di che tipo.

Testare un programma è un processo lungo che non è a costo zero. I test vanno innanzitutto creati,

eseguiti, e ne vanno verificati i risultati; il tutto va poi rieseguito più volte nel corso della vita di un

progetto. Per ottenere tutto questo è necessario quindi allocare tutta una serie di risorse preziose edi diverso tipo: tempo, conoscenza (test vengono creati da persone che hanno conoscenza del

software) ed esperienza (esistono figure professionali che fanno dei test la loro specialità). Come se

non bastasse, tutti i test che vengono creati nel tempo, pongono l’ulteriore problema della

manutenzione che riguarda sia il software oggetto di verifica che i test stessi. Un test che non viene

aggiornato di pari passo con il software, diventa un test inutile con relativo spreco di risorse. Da

questo generico quadro della situazione si può intuire il fatto che il processo di test ha un costo non

irrilevante. Per quale motivo quindi uno sviluppatore, ed a maggior ragione un’azienda, dovrebbe

decidere di investire sui test?

Di seguito vengono esposte tre motivazioni, partendo da quella più generica valida per qualsiasisoftware, arrivando a quella più pratica, valida per un azienda come O3-Enterprise che crea

dispositivi medici.

Qualità del software

Come si è detto, lo scopo dei test è riassumibile nel concetto di miglioramento della qualità del

software. Questo concetto, pur essendo a prima vista astratto, ha un valore molto importante che

può assumere diversi aspetti; nel caso di un’azienda, questi si riconducono tutti prima o poi ad un

mero valore economico. Più la qualità del software è alta, più alto è il valore stesso del programma.

Come si può, allora, calcolarne il valore?

Non è possibile calcolare il livello assoluto della qualità del software tramite misurazioni dirette, per

questo motivo si procede con un approccio differente. Ci si può chiedere invece che cos’è che fa

diminuire la qualità di un software; siccome il numero degli errori del software (o almeno quelli di cui

si è a conoscenza) è un parametro che può essere calcolato, ed essendo questi errori portatori di una

diminuzione della qualità del software, allora si può affermare che il software con il minor numero di

errori è un software generalmente migliore di uno con più errori (a parità di funzionalità).

Software Testing

Il “software testing” è un metodo empirico di investigazione per ottenere informazioni sulla qualità

del prodotto. Tale metodo può essere utilizzato per ottenere informazioni di vario tipo. Essoconsente di avere una visione sulla presenza o meno di bug (errorei nel software); sulla effettiva

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

3

conformità a degli standard che il software dovrebbe essere in grado di gestire; sullo stato di

avanzamento del progetto, evitando rilasci prematuri dovuti a componenti software non abbastanza

robusti o addirittura mancanti; sui limiti del software stesso e sui requisiti hardware, tramite l’utilizzo

di stress-test.

Testare un PACS

Oltre alle motivazioni valide per qualsiasi tipo di programma software, per i programmi di tipo PACS,

ed in generale per qualsiasi programma ospedaliero, sono valide delle ulteriori motivazioni per

investire sui test. I programmi informatici ospedalieri seguono delle linee guida dettate da

organizzazioni internazionali (principalmente IHE) composte sia da utenti che da produttori, che

hanno lo scopo di armonizzare i diversi programmi che solitamente coesistono all’interno di uno o

più sistemi informativi ospedalieri, e lo fanno incentivando l’utilizzo di standard condivisi e procedure

comuni (DICOM, HL7, SOAP). All’interno di un sistema informativo più grande infatti, ve ne sono

diversi che hanno la necessità di condividere dati anagrafici, clinici e diagnostici dei pazienti. Lo

scambio di dati viene quindi facilitato indicando taluni protocolli di comunicazione e standardpiuttosto che altri, in maniera tale da spianare la strada ai produttori di software che si trovano già

con delle specifiche, seppur generiche, da cui partire, e che consentono di poter avere un certo grado

di confidenza sul fatto che il loro prodotto sarà capace di interfacciarsi con prodotti terzi. O3-DPACS

non si sottrae a tutto questo discorso, ed anzi trova nei protocolli e negli standard indicati, dei

requisiti contro cui può e deve essere testato.

Marcatura CE

Il programma O3-DPACS, come accennato, è un software ospedaliero, classificato a tutti gli effetti

come dispositivo medico in quanto utilizzato per effettuare diagnosi, e come tale per poter essere

commercializzato in Europa, deve possedere dei requisiti minimi di qualità e di sicurezza, garantiti

della marcatura CE.

I dispositivi medici sono raggruppati in quattro classi che vanno da un livello minimo ad un livello di

massimo rischio per il paziente fino alla morte, e sono le classi I, IIa, IIb, III. L’attribuzione ad una di

esse dipende dalla destinazione d’uso indicata dal produttore, e può variare a seconda delle

peculiarità del dispositivo.

La classificazione dei sistemi PACS è argomento controverso in quanto non solo essi sono di difficile

collocazione all’interno delle quattro tipologie, ma la classificazione stessa può variare a seconda

delle caratteristiche della particolare implementazione sotto esame.Per facilitare la loro classificazione, la comunità europea ha pubblicato delle linee guida per i

dispositivi medici “borderline”, secondo le quali a seconda delle funzionalità offerte, un PACS può

ricadere soltanto nelle prime tre classi. Il motivo per il quale questa classificazione è importante, è

che per i dispositivi a partire dalla seconda classe in poi, è necessario l’intervento di un ente terzo che

autorizzi il produttore ad apporre la marcatura CE. Secondo queste linee guida, il sistema O3-DPACS

rientrerebbe nella classe I, per la quale la marcatura potrebbe essere assegnata in autonomia. È

altresì vero che nei bandi di gara europei non è raro che tra i requisiti che le aziende debbano

possedere, vi sia una certificazione del sistema qualità.

La ditta O3-Enterprise produce anche dispositivi di classe II (workstation radiologiche), per i quali ènecessaria la verifica della qualità del processo di creazione dei software della ditta. La certificazione,

ottenuta tramite ente terzo predisposto, valuta esclusivamente la qualità del processo e non del

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

4

prodotto finale. Per questo l’azienda ha creato dei protocolli da seguire rigidamente in modo da

rendere tale processo trasparente e valutabile. Poiché queste linee guida si applicano a tutti i

prodotti dell’azienda, anche la creazione di O3-DPACS dovrà seguire lo stesso procedimento di

controllo. Ovviamente la certificazione può essere concessa o meno in base al giudizio che viene dato

al processo utilizzato per lo sviluppo del software. La definizione del processo, pur non essendo

vincolata rispetto ad una normativa specifica, trova in diverse normative europee delle linee guida su

cui è consigliabile basarsi, e che se seguite possono garantire una maggiore probabilità che il

processo venga certificato. La norma di riferimento per i dispositivi medici è la ISO 13485.

La ISO 13485 è una norma che specifica i requisiti per i sistemi di gestione della qualità che

permettono ad una organizzazione di dimostrare la sua capacità di fornire dispositivi medici che

siano conformi ai requisiti regolamentari applicabili a tali dispositivi medici. È basata sulla ben più

nota EN ISO 9001:2000 ma con delle modifiche riguardanti la parte di “soddisfazione del cliente” e al

“miglioramento continuo”. 

Essendo una norma generale che si riferisce a dispositivi medici anche molto diversi tra loro, si deve

individuare quale parte della norma sia applicabile al processo di test in questione . La parte relativa

alla pianificazione della realizzazione del prodotto richiede esplicitamente che siano definite delle

attività di verifica, convalida, monitoraggio, ispezione e prove specifiche sul prodotto. Queste attività

devono produrre dei risultati che devono essere conservati e sono necessari a fornire evidenza che i

prodotti soddisfino i requisiti. Nella sezione relativa al controllo dei dispositivi di monitoraggio e

misurazione si richiede che l’organizzazione individui un sistema di monitoraggio e misurazione da

effettuare al fine di fornire evidenza sulla conformità dei prodotti rispetto ai requisiti, ed assicurarne

l’oggettività dei risultati. Ed ancora nella parte dedicata alla fase di design e sviluppo del prodotto,

viene richiesto che i risultati di questa fase, che hanno sempre lo stesso fine dell’assicurare che il

prodotto soddisfi i requisiti prefissati, siano documentati e conservati per dimostrare che il prodottosia stato effettivamente verificato. Infine, nell’attività di misura dell’efficacia della qualità del

sistema, la norma prevede che queste attività, fra le quali rientrano i test, devono essere descritte

includendo il metodo utilizzato, il criterio di accettazione o rifiuto, l’ambiente in cui sono eseguiti, i

dati di test utilizzati, i risultati ottenuti.

La ISO 13485 non è però l’unica norma che tratta di dispositivi medici, ve ne sono molte altre, ma di

sicuro interesse per quanto riguarda lo sviluppo di software per dispositivi medici vi è la CEI EN

62304. Questa norma descrive il processo relativo al ciclo di vita del software ed al suo interno si fa

esplicita menzione al sistema di test. In particolare la parte di testing del sistema software

approfondisce le norme già descritte nella 13485 per quanto riguarda i risultati derivanti dal design edallo sviluppo e successiva verifica.

La norma introduce il concetto di unità software nel processo di sviluppo del programma, e richiede

che il produttore definisca dei metodi e delle procedure per la verifica di queste unità, e che queste

verifiche siano effettuate attraverso l’esecuzione di test. Ciascuna verifica, inoltre, deve essere

validata secondo un criterio di accettazione definito a priori. Tra i criteri menzionati vi sono:

  Eventi eseguiti con una sequenza predefinita

  Allocazione di risorse in misura prevista

  Corretta gestione degli errori

  Inizializzazione delle variabili  Condizioni al confine

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

5

È importante notare che è richiesto che alla termine di questa fase, i risultati dei test vengano

conservati.

Ciascuna unità software, al termine dello sviluppo e successiva verifica, deve essere integrata nel

sistema nel suo complesso. In questa fase vanno definite altre procedure di verifica, questa volta atte

ad assicurare che con l’integrazione dell’unità software non siano stati introdotti difetti nel softwareintegrato in precedenza (regression testing).

Di tutti i test definiti ed eseguiti, il produttore deve essere in grado di fornire il risultato dei test

(successo, fallimento e lista di eventuali anomalie), una documentazione sufficiente che consenta di

ripetere il test, e l’identità di chi ha eseguito il test.

L’insieme delle unità software integrate nel sistema vanno a comporre il programma completo, al

quale il produttore deve prevedere un ulteriore set di test indispensabili per verificare che tutti i

requisiti del software siano stati coperti.

In conclusione, quello che si evince da queste normative è che il miglioramento del processo di test

(creazione, esecuzione, verifica) assume un’importanza chiave al fine della marcatura CE. Creare

un’infrastruttura per O3-DPACS che faciliti il test di porzioni di software che presentano difficoltà

nella loro definizione dovuti alla particolarità dell’ambiente server su cui il programma viene

eseguito, non si limita a migliorare la qualità intrinseca del prodotto, ma è anche un tassello

fondamentale per la certificazione del sistema qualità di O3-Enteprise.

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

6

 Analisi

Il sistema O3-DPACS

Introduzione

Il programma oggetto dei test di questa tesi, O3-DPACS, è come già anticipato, l’implementazione di

un sistema PACS “Picture Archiving and Communication System”, ovvero un gestore di immagini

medicali, con finalità di archiviazione, trasmissione e visualizzazione delle immagini diagnostiche

digitali. I file che vengono gestiti all’interno del sistema PACS sono in formato DICOM; esso è uno

standard che definisce sia il formato delle immagini digitali che il protocollo di comunicazione atto a

inviare e ricevere immagini, oltre che ad effettuarne la loro ricerca. In un tipico caso d’uso, i file

DICOM vengono creati dalle modalità diagnostiche (TAC, ecografie, etc.) ed inviati al PACS che le

archivia e le rende disponibili per la consultazione. La consultazione, tipicamente remota, avviene

tramite l’utilizzo di workstation di refertazione, le quali cercano e recuperano le immagini dal PACS; il

tutto avviene utilizzando il protocollo di comunicazione e formato dei file DICOM. Le funzionalità

tradizionali di un PACS sono quindi:

  Acquisizione dei file DICOM prodotti dalle modalità diagnostiche

  Archiviazione, per la gestione delle informazioni sulle immagini acquisite

  Indirizzamento dei dati verso le stazioni che lo richiedono (informazioni e immagini)

A queste funzionalità va aggiunta anche il servizio di “Worklist”, ovvero la gestione degli

appuntamenti, sempre tramite DICOM.

Oltre alle funzionalità base, O3-DPACS offre una serie di servizi secondari indispensabili, dedicati

all’integrazione con i sistemi informativi ospedalieri in cui viene installato. Queste integrazioni sono

rese possibili grazie all’adozione di un protocollo molto diffuso negli ambienti ospedalieri, HL7.

Questo protocollo è lo standard de-facto per lo scambio dei dati clinici fra sistemi informativi diversi.

I principali servizi offerti da O3-DPACS ed implementati tramite HL7 sono:

  Aggiornamento anagrafica pazienti

  Riconciliazione dei pazienti1 

  Inserimento ordini

  Gestione visite

Un’ulteriore integrazione offerta da O3-DPACS è data dalla possibilità di pubblicare in un sistema

centrale di condivisione di documenti, un particolare tipo di file DICOM (“Key Object Selection”)

tramite web-services. Questo file contenente riferimenti ad altre immagini DICOM, rende noto al

sistema di integrazione di livello superiore, che nel PACS vi sono le immagini relative all’esame del

paziente di turno, e che sono disponibili per il loro recupero (IHE XDS-I).

Per gestire le diverse configurazioni e per navigare tra i contenuti del PACS, vi è anche un apposita

applicazione web che comunica con i servizi del PACS e ne può pilotare il comportamento. Questa

1In un sistema informativo può capitare che vi siano due entità paziente che si riferiscono alla stessa persona

fisica. Il procedimento che riconduce le due entità in una sola viene chiamato riconciliazione

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

7

interfaccia web è in grado di effettuare operazioni di base quali la ricerca tra contenuti, visualizzare

immagini, gestire utenti e ruoli, e alcune operazioni di manutenzione.

Fino a qui sono state descritte le funzionalità macroscopiche di O3-DPACS da un punto di vista dei

casi d’uso. Da questo elenco però sono stati tralasciati i dettagli implementativi in quanto sono stati

oggetto di analisi approfondite e che vengono esposti brevemente di seguito per dare un ideagenerale della varietà di tecnologie coinvolte nel progetto; questi dettagli verranno poi descritti con

maggiore accuratezza nelle rispettive parti in cui esporrò l’approccio utilizzato per implementare i

casi di test.

Tecnologie coinvolte

O3-DPACS è un’applicazione server, scritta in Java, che viene fatta eseguire all’interno di un

“Application Container” per Java Enterprise Edition, in particolare JBoss (4.2 e 5.1).

La parte di comunicazione tramite protocollo DICOM è implementata estendendo le funzionalità

offerte dalle librerie open-source “dcm4che”, le quali offrono anche gli strumenti per la

manipolazione dei file in formato DICOM. Queste librerie nascondono parte del protocollo a più

basso livello (gestione dei socket sia client che server, e il parsing dello stream di dati).

L’altro protocollo di comunicazione esplicitamente creato per lo scambio di dati clinici è HL7. Per la

gestione di questo canale di comunicazione il PACS sfrutta la libreria “hapi”, che similmente a quanto

avviene con le dcm4che, fornisce un livello di astrazione utile per evitare la gestione dei socket e la

manipolazione dello stream dati.

I servizi web esposti per l’integrazione con XDS utilizzano invece una libreria scritta appositamente

dal team di O3, condivisa con altri progetti; la gestione delle connessioni per i web service trova

ausilio nelle librerie “httpClient” di Apache, manipolando quindi direttamente i messaggi SOAP.L’applicazione web per fornire l’interfaccia utente utilizza la tecnologia JSF (Ja va Server Faces), al cui

vertice vengono eseguiti componenti di tipo RichFaces. La visualizzazione delle immagini è stata

recentemente rivista e si basa invece sul framework Adobe Flex.

Tutte le informazioni che vengono gestite da O3-DPACS vengono immagazzinate in un DBMS. Il PACS

è in grado di funzionare sia utilizzando DBMS Oracle che MySql. La possibilità di utilizzare uno o

l’altro, come verrà spiegato in seguito, comporta un notevole sforzo in termini di programmazione e

conseguentemente anche di creazione dei test. Le comunicazioni tra applicazione e DBMS avvengono

con metodi diversi: query composte anche a runtime ed eseguite tramite JDBC; stored procedure

richiamate sempre tramite JDBC; utilizzo di Hibernate come framework ORM (Object RelationalMapping).

La gestione dei singoli servizi del PACS, tra cui la loro configurazione e ciclo di vita, è stata

implementata con JMX; i diversi MBean che rappresentano i servizi, espongono metodi per la loro

gestione. Le implementazioni vere e proprie dei servizi fanno invece largo uso di Enterprise Java

Bean.

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

8

Questa breve ma intensa carrellata di tecnologie utilizzate da O3-DPACS (non esaustiva) ha lo scopo

di evidenziare la quantità e la varietà di strumenti adottati nel sistema. Questo fatto ha avuto un

impatto non trascurabile, in quanto una buona parte del tempo è stata impiegata per il lavoro di

analisi delle diverse componenti, requisito fondamentale per poi costruire, laddove possibile, delle

pratiche, o addirittura dei piccoli framework, per creare i test veri e propri.

Il processo attuale Viene ora descritto quello che è il tipico processo di test utilizzato in O3-Enterprise per il programma

O3-DPACS, ma che viene applicato ad ogni progetto all’interno della ditta . Il processo è documentatoin dettaglio nel manuale di qualità, e viene seguito fedelmente in quanto anche da questo dipende la

certificazione ISO 13485. Ogni intervento (o caso, in inglese ‘issue’) su di un programma deve passare

attraverso una serie di stati, a partire dall’approvazione da par te del technical manager, che ne

valuta le motivazioni. Il caso, se ritenuto necessario, viene assegnato ad uno sviluppatore, il quale

come primo compito ha quello di effettuare l’analisi del problema e redigere un documento.

Dall’analisi si passa alla stesura del design dopo approvazione del documento da parte del capo

progetto, che dovrà approvare anche il documento di design. Solo a questo punto lo sviluppatore

potrà iniziare a scrivere il codice vero e proprio su di un branch del progetto (il branch in un sistema

di versionamento del codice è un ramo della linea principale, chiamata trunk). Al termine della

scrittura del codice, si passa alla fase di test. I test vengono inseriti durante ciascuna di queste fasi,

ma vi è il vincolo che per ogni requisito individuato nella fase di analisi, vi sia almeno un test

corrispondente. Se la fase di test si conclude positivamente, il caso viene marcato come pronto per

essere integrato nel sistema. Durante l’integrazione, che viene sempre svolta dal project manager, il

codice prodotto dallo sviluppatore per il caso in oggetto e presente nel branch del sistema di

versionamento, viene portato nella versione corrente del progetto (nel ‘trunk’), e vengono rieseguiti

tutti i test definiti per quell’issue. 

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

9

Col passare del tempo il progetto viene modificato e gli issue integrati si accumulano. Quando viene

deciso che il programma è pronto per essere rilasciato (secondo politiche aziendali), gli viene

assegnata una versione, e vengono rifatti tutti i test definiti in ciascun issue integrato a partire

dall’ultimo rilascio. Per procedere con il rilascio, vi sono degli ulteriori test obbligatori che vannosvolti per verificare le funzionalità fondamentali del programma (una sorta di regression test); infine

viene scelto un campione di test da issue datati (di rilasci precedenti) in maniera casuale.

È interessante notare che ciascun test inserito, viene eseguito un minimo di tre volte durante il ciclo

di vita dell’applicazione. Ovviamente durante la fase di sviluppo, i test molto probabilmente vengono

effettuati anche molte volte, a seconda del giudizio dello sviluppatore.

Dall’analisi del sistema di “bug tracking” utilizzato in O3, sono state estratte delle informazioni

relative all’andamento del numero di test in relazione a ciascuna versione e tempi di rilascio. 

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

10

Versione  release date  # issue  # test  media test/issue 1.5  06/09  12  0  - 1.6  09/10  40  50  1.25 1.7  09/10  9  21  2.3 1.7.1  10/10  1  1  - 1.7.2  10/10  1  1  - 

1.8  05/11  24  57  2.35 1.8.1  06/11  3  3  1 1.9  11/11  5  26  5.2 

Tabella 1 - Analisi storica dei test

Nota: le versioni a tre cifre non fanno parte del ciclo programmato dei rilasci, ma sono state create

per risolvere in velocità dei bug importanti; il numero di issue e test relativi sono bassi per questo

motivo. Inoltre la prima versione rilasciata (la 1.5) è stata fatta quando ancora non c’era un processo

di qualità definito, da cui la presenza dello zero nel numero dei test creati!

Sebbene i numeri siano bassi, si possono comunque notare delle tendenze:

  Il numero di test per issue è in aumento  La frequenza dei rilasci aumenta

Dalla somma di questi due fattori se ne ricava che in futuro sarà richiesto di eseguire sempre più

spesso un numero maggiore di test. Da qui un ulteriore conferma dell’esigenza di un sistema più

efficiente che possa essere d’aiuto per rendere questo processo più rapido.

Pro e contro del metodo attuale

Dall’analisi del processo di testing in uso si è cercato di cogliere quali sono i punti di forza,

valorizzandoli quanto possibile, e quali sono invece le debolezze, proponendo soluzioni che possano

essere integrate nel sistema attuale.

Regression test 

Una prima osservazione è possibile farla sui regression test. I test di questo tipo hanno lo scopo di

verificare che una modifica sul codice non abbia compromesso funzionalità non direttamente

collegate alla parte sottoposta a miglioramento. Nel metodo attuale i regression test individuati sono

quelli eseguiti ad ogni rilascio, e comprendono sia quelli definiti come obbligatori, sia quelli scelti a

caso tra i test degli issue più vecchi. Questo approccio ha sicuramente la sua validità, ma il punto

debole è che vengono eseguiti solamente ad ogni rilascio, evento con frequenza bassa (circa 2 rilasci

annui programmati). L’eventuale aumento della frequenza dei rilasci permetterebbe sì di effettuare

regression test più spesso, ma richiederebbero troppo tempo in quanto alcuni di questi test sonoanche di difficile esecuzione, e mancano completamente di automatismi.

All’approccio corrente va imputato un secondo punto a sfavore. I test designati come obbligatori ad

ogni rilascio non riescono a coprire in maniera adeguata tutte le funzionalità. Riuscendo a creare dei

test automatici, la parte di codice verificata con i regression test potrebbe aumentare di molto senza

incidere troppo sul tempo impiegato per la loro esecuzione. Eventuali test automatici, inoltre,

potrebbero essere eseguiti molto più spesso, senza dover aspettare il rilascio, ma potrebbero ad

esempio essere eseguiti anche ad ogni integrazione di un issue.

Unit test 

I test che vengono definiti per ciascun issue non sono quasi mai di tipo unit test. Questa particolare

tipologia di test viene utilizzata per verificare le funzionalità di singole unità logiche di codice, spesso

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

11

trovando corrispondenza nella definizione di un singolo metodo di una classe. Lo scopo è quello di

accertarsi che una classe esponga dei metodi che facciano esattamente quello che ci si aspetta dalla

loro definizione. Per come è stato pensato il processo esistente, questo tipo di test viene

completamente ignorato. Dai colloqui avuti con agli sviluppatori di O3, è emerso che è pratica

comune creare unit test durante la fase di programmazione, per esempio creando metodi Main

all’interno delle classi in cui viene verificato il comportamento della classe stessa. Purtroppo però

questo codice non viene versionato e i test vengono persi. La definizione di una pratica comune che

indichi come creare questo tipo di test, magari utilizzando un framework apposito come JUnit,

comporterebbe, a fronte di uno sforzo minimo, il salvataggio di questi test che possono essere

facilmente resi automatici e rieseguibili a piacimento.

 Scripted testing

La maggior parte dei test che vengono creati in O3-Enterprise rientrano invece nella categoria “test

script” (un'altra etichetta che viene utilizzata per definire questo tipo di test è “checklist test”). Un

test così definito è composto da una serie di istruzioni scritte che devono essere eseguite sul sistemasotto test per verificarne il funzionamento. Quello che contraddistingue questo tipo di test è che le

istruzioni sono scritte in maniera informale, e l’esecuzione non è automatizzata ma destinata ad una

persona che deve eseguire le istruzioni secondo quanto scritto. Questi test non scendono quasi mai

al di sotto di un certo livello di dettaglio, e quello che testano sono principalmente dei casi d’uso del

programma. Per creare un test di questo tipo va specificato:

  Ambiente di esecuzione (compreso lo stato iniziale del sistema)

  Una serie di istruzioni da eseguire in sequenza

  Un risultato aspettato

Analizzando questo tipo di approccio si identificano due fasi principali: progettazione del test edesecuzione del test. Ciascuna di queste fasi presentano le seguenti criticità.

Esecuzione

L'esecutore del test deve comprendere l'intento di chi ha scritto il test. L'intenzione del

creatore del test non è sempre esplicita nella descrizione e va quindi compresa dal contesto.

Se non c'è la comprensione dell'intento reale del test, allora l'esecuzione del test diventa una

mera esecuzione di istruzioni (il che non è sempre male, ma la potenzialità di un test creato

ed eseguito da una persona può essere sfruttata molto meglio, per i test automatici si

possono sfruttare le altre tecniche oggetto della tesi)

Design

Colui che deve scrivere il test deve essere in grado di indovinare con una certa precisione il

livello di conoscenza del tester che eseguirà il test. La scrittura di test richiede pazienza,

bravura nello scrivere, un livello minimo di empatia con l'esecutore del test (che talvolta è

sconosciuto). Questo è un processo tipicamente noioso, lo sviluppatore non è invogliato a

scrivere test ed una immediata conseguenza è la cattiva qualità dei test stessi.

Nel caso di applicazioni complesse, per fare in modo che un tester sia in grado di eseguire un test, a

meno che non sia lui stesso uno degli sviluppatori dell'applicazione, è necessario fornire una

descrizione molto dettagliata dei passi da eseguire, a livello anche molto basso. Es.

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

12

1. Mettere un breakpoint nella classe X alla riga Y e poi alla riga Z

2. Lanciare l'applicazione in debug

3. Al punto Y verificare che il valore della variabile A sia diversa da null

4. Proseguire facendo l’operazione P 

5. Al punto Z verificare che il valore della variabile A sia pari al valore contenuto nella colonna C

della tabella T con chiave primaria K.

Questo tipo di descrizione di test può sembrare estremo, ma ci sono casi in cui è necessario e viene

effettivamente utilizzato.

Un test così fatto presenta diversi problemi. Un primo problema è che nel momento in cui il codice

verrà modificato, la descrizione del test diverrà senza senso (le righe di codice in cui mettere i

breakpoint non corrisponderanno più). Se la modifica riguarda porzioni di codice ampio con relativo

refactoring del codice (variabili rinominate, o metodi spostati da una classe all'altra), allora l'intero

test avrà perso di significato.

Un ulteriore problema è dato dal fatto che con test di questo tipo il tester non acquisisce nessuna

conoscenza dell'applicazione, né aumenta la sua abilità nel testare.

Non ci sono però solo fattori negativi in questo tipo di test, che invece è uno strumento di verifica

con potenzialità molto elevata. La capacità di una persona che legge il test e lo esegue, permette

l’esecuzione di test anche molto complessi in tempi relativamente brevi. Questo è tanto più vero

quante più operazioni di tipo diverso tra loro sono richieste dal test. Si pensi anche ad esempio a ai

test necessari per verificare che l’applicazione web abbia l’aspetto voluto. Probabilmente prima o poi

si potrebbe arrivare alla definizione di un test automatizzato che riesca a fare la stessa cosa, ma con

tempi estremamente alti, e con una fragilità altrettanto alta. È invece molto più rapido e

probabilmente anche molto più affidabile relegare questo tipo di verifiche ad una persona che è in

grado di giudicare se i requisiti sono soddisfatti o meno.

Oltre alle interfacce, test di questo tipo sono indispensabili laddove le componenti coinvolte sono

numerose e di tipo anche molto diverso tra loro. Generalmente si tratta di test di integrazione a più

alto livello in cui la funzionalità testata coinvolge programmi esterni con cui il sistema deve

comunicare. Test di integrazione si trasformano in test dei casi d’uso, dove prima o poi si dovranno

testare le funzioni dell’applicazione dall’inizio alla fine, senza ricorrere a strumenti che simulano

componenti esterne, cosa che come spiegherò, è un requisito quasi fondamentale per l’automazione

dei test.

Per sfruttare meglio questo sistema è quindi necessario fare una riflessione sull’obbiettivo di ogni

singolo test. Va quindi evitato di scrivere dei script-test con un livello di dettaglio troppo elevato otroppo specifici (unit test), in quanto troveranno applicazione nei sistemi di automazione proposti

nella tesi; va invece preferito questo tipo di test laddove l’automazione è di difficile realizzazione.

Ripetibilità dei test 

Un ultima considerazione sul processo esistente va fatta sulla ripetibilità dei test, intesa sia come

difficoltà nel ripetere un test, sia come probabilità che un test venga rieseguito più volte. Gli attuali

test sono definiti tutti nella stessa maniera (script-test), sia che essi vengano eseguiti con una certa

frequenza (come ad esempio i regression test), sia che la loro utilità si esaurisca all’interno dell’issue

in cui vengono definiti. La mia proposta mira a catalogare i test in queste due macro tipologie. Il

lavoro di creazione di test e loro automazione si concentrerà quindi sui test ad elevata ripetibilità.

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

13

All’interno poi di questa grande categoria, andrò a distinguere ulteriormente i test in base ad altri

criteri che vengono esposti di seguito.

Teoria dei test 

Definizione

Il software testing viene definito come il “processo di operare un sistema o una sua componente

sotto particolari condizioni, osservando o registrando i risultati, e valutando alcuni aspetti del sistema

o della componente” (IEEE standard 610.12-1990).

È una tecnica che tipicamente da indicazioni su come effettuare le seguenti operazioni:

  Analizzare la situazione di partenza

  Modellizzare lo spazio dei test

  Decidere quali parti del sistema coprire

  Determinare le discriminanti per il successo/fallimento (oracoli)

  Configurare il sistema di test

  Eseguire il sistema

  Osservare il sistema

  Valutarne i risultati

Da questa lista sintetica si ricava la metodologia descritta di seguito per creare un test.

Un programma può essere immaginato come una collezione di variabili in ingresso e in uscita, ed è

necessario analizzare quali sono i valori che possono assumere. A partire da questi valori, si procede

applicando un modello di campionamento che separi tutti i possibili valori in diversi gruppi a seconda

della loro capacità a far fallire il programma in esame. Per ogni variabile, dividerne i possibili valori ingruppi di equivalenza. Creare un test prendendo almeno un valore da ciascun gruppo così

determinato.

Sarà poi necessario decidere quali combinazioni di variabili sono da considerare. Si devono decidere

le condizioni finali del sistema in base alle quali è possibile concludere che un test è riuscito o è

fallito. Descrivere la configurazione del sistema e dell’ambiente in cui esso viene fatto eseguire. Solo

a questo punto è possibile eseguire il test, osservarne il comportamento e valutare il successo dal

risultato.

Tipi di test 

In letteratura si usa catalogare i test in base al loro scopo e destinazione d’uso. Di seguito vengono

illustrati i 5 tipi di test più utilizzati. Esistono ovviamente anche altre categorie, che vengono ricavate

secondo i criteri più diversi, ma ritengo che quelle che seguono sono di gran lunga quelle più

riconosciute dai maggiori testi che trattano dell’argomento e dalle risorse in rete. 

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

14

In questa suddivisione, il criterio è una miscela tra l’oggetto sottoposto a verifica e lo scopo della

verifica. Man mano che ci si muove dal livello più basso a quello più alto, i test diventano più

funzionali e richiedono che porzioni sempre maggiori dell’applicazione siano presenti fino ad arrivare

alle due categorie più estese dove si verifica il programma nella sua totalità.

Unit test 

Lo scopo principale degli unit-test è verificare che l’applicazione si comporti come da requisiti e

scovare difetti nel codice nelle primissime fasi di sviluppo. Anche se i test di altro tipo come i test

funzionali perseguono gli stessi obbiettivi, gli unit-test offrono altri vantaggi per i quali vengono

scelti:

  Maggiore copertura del codice rispetto a test funzionali

  Incoraggiano il refactoring

  Individuano regressioni

  Documentano il comportamento voluto

  Introducono delle metriche di misura del codice

Gli unit test permettono una copertura del codice non raggiungibile con altri sistemi. Questa è una

possibilità che deve essere sfruttata laddove ve ne sia una reale necessità. La copertura del 100% del

codice è un obbiettivo che comporta un notevole impiego di risorse, con un ritorno in termini di

efficacia discutibile. Vi sono però dei casi in cui una copertura il più ampia possibile di porzioni di

codice particolarmente sensibili è da ricercarsi. Unit test hanno anche il vantaggio di riuscire a

simulare condizioni di errore che sono altresì molto difficili da ottenere con test funzionali.

Essendo tra i primi utilizzatori del codice scritto, gli unit-test mettono per primi in evidenza eventuali

difetti nell’architettura del codice. Scrivere test costringe lo sviluppatore a creare codice facilmente

testabile, isolato (basso accoppiamento), e con delle API (interfacce di programmazione) chiare edesplicative.

Una serie di test creati per una classe è anche un efficace metodo per documentare il

comportamento voluto della classe e un valido esempio di utilizzo di quella classe.

Anche per gli unit test si possono individuare delle categorie di test, distinguibili secondo un criterio

che verrà utilizzato durante la creazione dei test per O3-DPACS. Queste categorie si differenziano per

i “confini” del codice sotto test. 

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

15

Tipo di test Descrizione

Test di unità logiche Test che si focalizza su un singolo metodo. I confini possono esserecontrollati utilizzando metodi quali la creazione di Mock e Stub

Test di integrazione di unità Test che si concentra sull’interazione tra diverse unità logiche. Il numero

di unità coinvolte può variare fino a coinvolgere anche componenti ditipo diverso (DBMS, file system, network)

Test funzionale di unità Test che estende i suoi confini fino a coinvolgere stimoli esterniall’applicazione e verificare la reazione del programma. La definizione di

questo tipo di test si basa sui casi d’uso

Tabella 2 - Tipi di unit-test

L’interazione fra i diversi tipi di test sono illustrati meglio nella seguente illustrazione. L’utilizzo di

tutti e tre i tipi consente di coprire bene l’applicazione e conferire maggiore confidenza quando si

tratta di fare dei cambiamenti.

Esistono altri due tipi di test molto utilizzati, ma che non rientrano nello scopo della tesi e che includo

per completezza. Questi sono stress-test e test di accettazione. I primi vengono utilizzati per

conoscere quali sono i limiti strutturali dell’applicazione, come ad esempio il numero di utenti

contemporanei che il programma è in grado di servire con prestazioni accettabili, su di un

determinato hardware. Il secondo tipo di test viene invece utilizzato quando vi è un committente che

paga per il prodotto che si sta sviluppando ed è lo strumento decisionale per capire se sono stati

soddisfatti i requisiti del cliente. Questi test sono spesso dei test di casi d’uso e di performance, ma

non escludono anche test più soggettivi come la valutazione dell’aspetto dell’interfaccia. È

importante notare che i test di accettazione non vengono eseguiti dal team di sviluppo ma dal cliente

stesso.

Incidenza dei bug nel sistema

Prima di proseguire con la progettazione di quello che sarà il sistema di test da realizzare, si è cercato

di capire se esistono delle parti di programma più esposte ad errori di altre su cui concentrare gli

sforzi, ed è stato fatto andando a vedere lo storico dei bug degli ultimi rilasci.

O3-Enterprise utilizza un sistema di tracciabilità dei difetti (infelice traduzione personale di “bug-

tracking system”) per registrare tutti gli eventi legati al software, inclusi quindi i bug scovati e loro

stato di risoluzione.

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

16

Dal lavoro di ricerca è emersa la tabella presente in appendice, dalla quale sono stati estratti i

seguenti dati riguardanti l’andamento generale dei difetti segnalati.

Nota sulla classificazione dei bug:

  Minor: sono errori che non pregiudicano il funzionamento del sistema la cui risoluzione può

essere rimandata

  Major: difetti del software che vanno risolti quanto prima ma che non pregiudicano il

funzionamento globale

  Critici: compromettono il funzionamento di almeno una parte fondamentale del programma

ed hanno la priorità massima

PACSCORE PACSWEB WADO totale

Minor Major Critical Minor Major Critical Minor Major Critical Minor Major Critical

2011  6 2 0 12  0 0 4  0 0 20  4 0

2010  14  7 1 4  1 4 3  1 0 21  9 5

2009  6  5 2 5  4 2 2  2 1 13  11 5

2008  0  4 0 0  5 0 0  0 0 0  9 0

Tabella 3 - Analisi storica dei bug

Osservazioni: 

  Tra il 2009 e 2010 il numero dei bug critici e major è rimasto praticamente invariato. Sono

aumentati i bug minor. 

  Tra il 2010 e 2011 non è emerso nessun bug critico, e i major sono stati dimezzati. Il numero

dei bug minor è rimasto alto.   Nel 2008 il sistema di bug tracking era ancora ai primordi quindi non può far testo. 

Il dato più rilevante è che il numero dei bug minor è sempre alto. Difetti di questo tipo sono da

imputarsi all’introduzione di nuove funzionalità del sistema. I controlli effettuati sui casi d'uso più

critici hanno raggiunto un buon livello di efficacia, rimane invece basso il livello sui servizi di nuova

creazione, dove unit ed integration test possono fare la differenza. 

Dopo aver identificato quali tipi di test mancano maggiormente nel sistema, il passo successivo è

stato vedere se ci sono delle aree più predisposte a difetti su cui concentrare il mio lavoro. Nella

seguente lista sono incluse quelle parti di O3-DPACS che hanno avuto un incidenza maggiore di bug.

Dal totale dei difetti del software registrati, sono qui riportate soltanto quelle aree alle quali possono

essere attribuite almeno il 10% dei bug totali (per l’elenco completo vedere la tabella in appendice):

1.  Servizi dicom: 23%

2.  Gestione del DBMS: 14,5%

3.  Servizio di Worklist: 12,5%

4.  Gestione dei servizi del PACS (ciclo di vita e configurazioni): 10,4%

5.  Il restante 40% riguarda problemi non catalogabili in macro aree.

Questa lista vuole essere una sorta di scaletta da cui partire per affrontare il lavoro assegnando delle

priorità. Va notato che analizzando l’elenco completo con maggiore attenzione, si può osservare

come i problemi legati alla gestione del DBMS si trovano anche in aree diverse da quella

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

17

esplicitamente assegnatagli, acquisendo così un’importanza ancora maggiore, motivo per il quale è

stato dato molto spazio ai test legati al DBMS.

 Analisi delle classi e package

È stata analizzata in dettaglio la struttura del sistema O3-DPACS con lo scopo di assegnare a ciascuna

classe (o insieme di classi), il tipo di test che è possibile creare. Per ogni classe è stata valutata la

possibilità di creare un unit-test corrispondente e l’eventuale utilità. In alcuni casi è stato possibile, in

altri invece ciò è estremamente difficile a causa di un alto livello di accoppiamento tra classi.

L’alternativa è quindi un test di integrazione che coinvolga la classe in esame assieme a tutta una

serie di classi da cui esso dipende. In quest’ultimo caso sono state indicate quali componenti sono

coinvolte. Ad esempio per le classi che non mantengono uno stato interno ma offrono funzioni di

utilità come potrebbe essere il calcolo di un hash, è stata prevista la creazione di un unit-test. Per

classi più complesse come ad esempio quelle che gestiscono la persistenza dei metadati a partire da

oggetti dicom, il test non può che essere di tipo integrazione.

Il criterio utilizzato per “marcare” le classi che possono essere delle buone candidate da sottoporre a

unit test, è stato vedere se di volta in volta le seguenti condizioni erano verificate o meno.

Un test non è unit-test quando:

  Comunica con un DBMS

  Comunica attraverso la rete

  Coinvolge il filesystem

  Ha bisogno di configurazioni speciali dell'ambiente

Un unit-test invece deve essere:

  Veloce

  Ripetibile

  Indipendente

  Auto esplicativo

  “Opportuno” 

Inoltre qualsiasi classe che non abbia alcuna logica interna (classi 'entità'), non deve essere oggetto di

unit test.

Sono stati scartati metodi che accedono al database o alla rete, metodi che chiamano in cascata altre

classi (a meno che non siano facilmente interpretabili da classi Stub o Mock), e sono inclusi metodiche hanno una logica il cui risultato cambia in base ai parametri d'ingresso. Metodi che modificano lo

stato o il comportamento dell'applicazione non rientrano in questi casi.

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

18

package “it.units.htl.dpacs.helpers” 

Anonimizer Unit test

Compression Unit test

DateHelper Unit test

DateTimeRange Unit test

FileHasher Unit test

GlobalConfigurationLoader Integration test (DBMS)

MailerSystem Integration test (DBMS)

PhysicalMediaTimerTask Integration test (DBMS)

package “it.units.htl.dpacs.valueObjects” 

Tutte le classi (Privi di logica)

package “it.units.htl.dpacs.core” VarLoader Unit test

Package “it.units.htl.dpacs.dao” 

StoragePerformer Integration test (FileSystem)

UserManager Integration test (DBMS)

Tutte le altre classi Functional test (Classi EJB)

UidGenerator Unit Test

DcmFramesToMF Integration test (DB, FS)

DcmQuerier Integration test (Dicom, networking)

KosBuilder Unit test

StudiesVerifierWorker Integration test (DBMS, FileSystem, networking)

XdsClient Integration test (networking)

XdsMessageCreator Integration test (FileSystem, DBMS)

Package “it.units.htl.dpacs.servers” 

Tutte le classi Functional Test (Classi MBean)

Package “it.units.htl.dpacs.servers” 

Tutte le classi Functional Test (Classi MBean)

Package “it.units.htl.maps” 

Classi entità JPA (privy di logica)

Classi DAO Unit test

Tabella 4 - Analisi delle classi e dei package

Questa tabella non è esaustiva, il numero totale delle classi del progetto O3-DPACS è circa 300. Le

classi non in elenco sono state omesse in quanto interfaccie, classi abstract, classi appartenenti al

modulo web, ed altre classi che hanno pochissima logica interna e sono per lo più degli aggregatori di

dati.

Una nota particolare riguarda il modulo web. Esso presenta delle caratteristiche molto differenti datutto il resto del progetto O3-DPACS. Al suo interno ci sono diverse servlet con della logica interna,

filtri (es. per l'autenticazione), ed altre classi che sono strettamente legate con il ciclo di vita di

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

19

un'applicazione web. Il test di questo progetto richiede un approccio specifico, con l'utilizzo di

tecniche e strumenti appositi. Ci sono inoltre delle integrazioni con tecnologie diverse da java (Flex),

e la parte di presentazione si basa sulle Java Server Faces arricchite con le librerie di RichFaces, tutte

infrastrutture che rendono particolarmente difficile la creazione di test automatici che

richiederebbero strumenti specifici come JSFUnit, o Selenium. Vista quindi la natura di questo

progetto e dopo l'analisi iniziale, è stato scelto di tralasciare questa componente e concentrare gli

sforzi sul test del resto del progetto.

Database Testing

Testare lo strato software che si occupa della gestione del DBMS pone diverse problematiche:

  Impossibilità di isolare la classe in esame (deve accedere al DBMS)

  Complessità del test (inserimento dati di test, pulizia finale)

  Velocità (overhead dovuto all’apertura/chiusura delle connessioni e accesso al filesystem) 

Per risolvere i primi due problemi si può ricorrere a strumenti più o meno complessi che vengono

incontro alle esigenze dello sviluppatore che vuole evitare di dover scrivere troppo codice solo per

creare unit test. In questi casi infatti la tentazione di evitare di scrivere test diventa sicuramente

molto alta, e la probabilità di non aggiornare test vecchi lo è ancora di più. Uno di questi tool utilizzati

è DBUnit, un'estensione di JUnit che verrà introdotta in seguito.

Il terzo problema, quello legato alla velocità dei test, è un problema che si può definire tale nel

momento in cui vi sono centinaia di test da eseguire prima di ogni build, rendendo vano di fatto il

vantaggio di avere unit test eseguibili ad ogni modifica del codice.

Nel caso dell'applicazione O3-DPACS questo problema ancora non si pone essendo stato sviluppatoun numero di test del database non elevato. Il problema viene quindi rimandato, anche perché la

soluzione più gettonata dalla letteratura di questo momento è quella di diminuire il tempo di

comunicazione con il database portandolo direttamente sul computer dello sviluppatore (vi sono casi

in cui più sviluppatori si trovano costretti ad utilizzare un'unica istanza remota del database per fare

test e sviluppare regolarmente). Ma è possibile fare di meglio utilizzando un DBMS in memoria il

quale non deve accedere alle risorse del filesystem diminuendo il tempo di accesso sia in scrittura

che in lettura ai dati (Hypersonic DB, Derby, Java DB, SQLite).

Purtroppo però non è sempre possibile ricorrere ad un DBMS di questo tipo. L'applicazione O3-

DPACS infatti, sfrutta pesantemente le ottimizzazioni che sono ottenibili con le Stored Procedure diOracle e MySQL. Non avendo uno strato di astrazione del database, l'applicazione non è in grado di

utilizzare database che non siano quelli sopracitati, né tantomeno database "volatili".

Ritornando ai problemi legati alla complessità del codice necessario all'interazione con il database, i

tipici test che vengono creati sono quelli che verificano la correttezza delle operazioni di inserimento

ed estrazione dei dati. Test più avanzati hanno a che fare con le chiamate a Stored Procedure. Il

risultato di tutti questi casi, però, dipende fortemente dallo stato in cui si trova il database nel

momento della loro esecuzione. Se al termine di un test di inserimento di dati in una tabella avente

dei vincoli di unicità, il test non "pulisse" il database, una seconda esecuzione dello stesso test

comporterebbe il fallimento dello stesso!

Pensando invece al caso dell'estrazione di dati, il database dovrebbe essere opportunamente

riempito con dei dati validi, ed eventualmente vuotato al termine del test. Tutte queste operazioni da

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

20

effettuare prima e dopo ogni test non sono impossibili da effettuare, ma sono sicuramente molto

verbose da codificare, con un’elevata probabilità di commettere degli errori, ritrovarsi poi a testare il

codice del test stesso. DBUnit risolve parte di questi problemi permettendo di fatto una

semplificazione della scrittura dei test di database, rendendo più facile l'inizializzazione dello stato

del database e riportandolo allo stato iniziale una volta terminato tutto.

Nell'applicazione di O3-DPACS, la gestione dei dati svolge un ruolo di fondamentale importanza; per

lo più si le interazioni con il DB sono operazioni "delicate" in quanto essendo complesse, hanno

maggior probabilità di contenere degli errori. Per questo motivo per la creazione dei test del

database è stata posta un'attenzione maggiore, cercando diverse strategie per semplificare il

compito. I sistemi di accesso al database utilizzati nell'applicazione sono di vario tipo a seconda delle

necessità. Per operazioni molto semplici come potrebbe essere la SELECT per ottenere il valore di

una singola colonna in una tabella di tipo chiave-valore, vengono quasi sempre utilizzate le api JDBC

in cui la query SQL è residente nel codice stesso. Man mano che le operazioni da fare sono sempre

più complesse, l'approccio utilizzato diventa quello delle chiamate a Stored Procedure, che sono

invece presenti nel DBMS. C'è un ulteriore approccio, utilizzato prevalentemente in quella partedell'applicazione dedicata all'interfaccia web, che sfrutta invece Hibernate come astrazione del

database.

Test funzionali

Dopo aver individuato un possibile elenco di unit test e di integrazione, si è passati all’analisi dei test

che sono attualmente definiti, dai quali è stata ricavata una lista di test che possono essere oggetto

di automazione con conseguente riduzione dei tempi per la loro esecuzione. Questi test, essendo

derivati da quelli attuali, sono tutti di tipo funzionale, e ciascuno di essi descrive un tipico caso d’uso

dell’applicazione. Da notare che pochissimi dei seguenti test sono inseriti nella lista di quelliobbligatori da effettuare ad ogni rilascio. Una loro automazione consentirebbe di poterli inserire tutti

senza problemi.

  Test funzionali sul protocollo DICOM

o  Test di storage (salvataggio di immagini e metadati) di più studi (esami) contenenti

dati su paziente e studio da individuarsi tramite classi di equivalenza. Il risultato

dovrebbe essere un test eseguito più volte con dati sempre diversi.

o  Test di retrieve (recupero di immagini e metadati) con dati individuati come sopra

tramite classi di equivalenza.

o

 Test di query (ricerca nell’archivio tramite metadati) 

  Test funzionali sul protocollo HL7

o  Gestione dei messaggi di update

o  Gestione dei messaggi di riconciliazione

o  Gestione dei messaggi su appuntamenti

  Test dei sistemi opzionali e di integrazione

o  Creazione ed invio dei messaggi XDS-I (web-service)

o  Servizio di Worklist (liste di lavoro)

o  Servizio di cancellazione studi

o  Anonimizzazione

o  Compressione studio  Generazione a runtime di file jnlp (java web-start)

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

21

o  Recupero di immagini via wado

o  Task monitoraggio memorie di massa

o  Test algoritmi (hash, base64)

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

22

Tecnologie utilizzate

Nell’arco di tutto il periodo di lavoro su questa tesi, sono state valutate diverse tecnologie chepotessero rivelarsi utili per facilitare la scrittura dei test. Quando in seguito varrà descritto in

dettaglio il processo che ha portato alla creazione dei test in un modo piuttosto che in un altro, ci

saranno dei riferimenti a tre software in particolare più alcune tecniche di programmazione che sono

state impiegate. Queste software sono JUnit, Mockito, DBUnit mentre le tecniche di

programmazione vedono l’utilizzo del pattern “Dependency Injection”, l’utilizzo di classi “Stub” e di

classi “Mock”.

JUnit 

Questo software è probabilmente il framework per la creazione di test più conosciuto e diffuso, enon soltanto in ambiente Java. Come suggerisce il nome, è nato per facilitare la creazione di unit test.

Non è il solo framework esistente di questo tipo: il diretto concorrente è TestNG (“Next

Generation”). Quest’ultimo è un progetto più recente, creato per colmare le principali lacune di

JUnit:

  Supporto nativo ai test parametrici

  Ordine di esecuzione dei test

  Riesecuzione dei soli test falliti

Nonostante queste differenze la scelta è ricaduta comunque su JUnit in quanto le stesse

caratteristiche sono ottenibili tramite l’utilizzo di plugin. Questi sono infatti molto più numerosiproprio grazie al fatto che JUnit è sul mercato da più tempo, cosa che ha influito positivamente anche

sul livello di adozione che è più capillare. A questo dobbiamo aggiungere il fatto che in Eclipse (l’IDE

di sviluppo utilizzato in O3-Enterprise) vi è il supporto nativo a questo framework.

Dalle interviste effettuate agli sviluppatori dell’azienda era emerso che degli unit test vengono

tipicamente creati durante la fase di sviluppo senza seguire una metodologia particolare, ed infine

“cestinati” una volta accertato il corretto funzionamento della classe. L’usanza è quella di creare un

metodo Main all’interno della classe oggetto di verifica e provare a richiamarne i metodi. La verifica

può avvenire semplicemente osservando lo standard output sul quale vengono stampati i risultati dei

metodi.Questo approccio presenta diverse debolezze:

1.  Un unico test per classe. Potendo inserire un singolo metodo Main per ciascuna classe, anche

il test può essere definito una sola volta. Per ovviare a questo si commentavano man mano

porzioni del metodo Main a seconda di quello che era il metodo da esaminare.

2.  Esecuzione manuale di un test per volta. Per l’esecuzione si deve specificare di volta in volta

qual è la classe sotto esame contenente il metodo Main.

3.  Struttura variabile. Ogni sviluppatore utilizza un suo sistema, che può variare anche da classe

a classe, rendendo difficile il suo riutilizzo per chi non è l’autore. 

4.  Mix di codice operativo e codice di test nella stessa classe. Questo oltre ad esserestilisticamente brutto, rende anche difficile capire al volo se una classe ha un rispettivo test.

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

23

Tutti questi problemi si risolvono impiegando JUnit nel seguente modo:

1.  La pratica comune suggerisce di creare una classe di test JUnit associata alla classe sotto

esame. Al suo interno è possibile creare tanti metodi quanti sono i casi che si vogliono

verificare (tipicamente almeno uno per ogni metodo pubblico).

2.  È possibile definire una “suite” che raggruppa più test JUnit. In questo modo è possibileeseguire tutti casi definiti in tutte le classi della suite in una sola volta.

3.  JUnit impone che ogni test-case sia annotato con “@Test”, rendendo esplicita la sua

definizione. Inoltre prevede che ci possano essere dei metodi che vengono richiamati prima e

dopo l’esecuzione di ogni test, tramite l’utilizzo di altre annotazioni. Tutto questo, assieme

alle convenzioni di scrittura suggeriti da JUnit, permette di mantenere una struttura coerente

anche tra sviluppatori diversi.

4.  JUnit suggerisce che per ogni classe da testare, venga creata una classe con lo stesso nome a

cui aggiungere il suffisso “Test”. In questo modo vi è una chiara distinzione tra qual è il codice

operativo e quale ne verifica il funzionamento, mantenendo al contempo evidente la loro

relazione.

Un’altra convenzione utilizzata in questo lavoro è quella di dichiarare nella classe di test, una

variabile di nome ‘instance’ dello stesso tipo della classe sotto esame. In questo modo sarà evidente,

in qualsiasi test, qual è l’istanza della classe sotto test. 

Per chiarire meglio l’utilizzo di questo strumento viene fornito un semplice esempio. Si supponga di

avere una classe ‘Anonimizer’ che espone un metodo pubblico ‘anonimize’ che accetta come

parametro un oggetto di tipo ‘DicomMetaInfo’. Si procederà quindi a creare una classe JUnit così

formata:

In JUnit i metodi annotati con @Before e @After vengono chiamati prima e dopo l’esecuzione di ogni

test, anche per quelli definiti nella stessa classe. Infatti per ogni metodo annotato con @Test, il

motore di JUnit istanzia una classe distinta. In questo modo l’esecuzione di un test non può avere in

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

24

nessun modo conseguenze sull’esecuzione di un secondo test. Se da un lato è un vantaggio, dall’altro

rende difficile l’esecuzione di test dove l’esecuzione di uno dipende dal risultato di un altro. 

Poiché i metodi contrassegnati come Before ed After vengono richiamati in ogni test-case definito,

non è il posto ideale dove effettuare delle operazioni di inzializzazione costose in termini di tempo

(come ad esempio la connessione al DBMS). Queste operazioni, dove possibile, è consigliabileinserirle in metodi annotati con @BeforeClass ed @AfterClass. Questi metodi, che devono essere

statici, vengono richiamati solamente una volta per tutti i metodi @Test definiti nella classe. In

questo caso una limitazione deriva dal fatto che tutte le risorse inzializzate in questi metodi devono

per forza di cose essere statiche, e condivise tra tutti i test contenuti nella classe.

Un’ultima nota riguarda la collocazione fisica delle classi di test. La presenza simultanea di classi

“vere” e rispettive classi di verifica all’interno dello stesso package può risultare caotica. Per ovviare

al problema è possibile sfruttare le possibilità offerte dagli IDE di sviluppo. In Eclipse ad esempio si

possono definire più cartelle per i sorgenti di uno stesso progetto. Mantenere una cartella separata

contenenti i sorgenti dei test rende il progetto più strutturato. Questo faciliterà anche il compito

dell’automazione dell’esecuzione dei test; come verrà mostrato, sarà possibile programmare un task

che esegua tutti i test-case di JUnit presenti soltanto nella cartella specificata.

Classi Stub e Mock (Mockito)

I principi su cui si fonda il concetto di unit-test che sono stati esposti fin’ora, per i quali un test deve

verificare il comportamento di una sola classe o addirittura di un solo metodo, sono difficilmenteriscontrabili nella realtà. Il motivo è che le classi che non hanno dipendenze verso altre classi (che

non siano quelle della distribuzione standard di Java), in un progetto vero, sono poche. È tipico il caso

in cui ci sono dei riferimenti a classi di utilità per fare delle conversioni, per recuperare configurazioni

varie, o per avere lo stato di altre classi da cui si dipende. Tutto questo però, oltre ad essere indice di

una tecnica di programmazione datata in quanto non pensata per agevolare la creazione di test,

pone dei problemi che devono essere comunque risolti.

L’obbiettivo finale è isolare completamente la classe di cui vogliamo verificare il comportamento dal

resto del sistema. Per riuscire in questo compito si può procedere nel seguente modo: identificare

quali sono le variabili e i loro tipi che creano dipendenze con il resto del programma. Una voltaidentificate, è necessario capire come sostituirle in qualche modo con delle variabili di tipo “simile”

(stessa interfaccia, o classi figlie). Queste nuove classi devono essere create di volta in volta, e la loro

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

25

logica interna va programmata in base alle esigenze di quel specifico test; spesso è sufficiente creare

delle classi completamente prive di logica.

Questa è una tecnica che viene utilizzata per creare delle classi “fantoccio”, le quali possono

assumere due nomi differenti a seconda di alcuni dettagli sulla loro particolare implementazione. Si

parla quindi di classi “Stub2

” e di classi “Mock3

”. Sebbene entrambe queste tecniche abbiano lo scopo di sostituire delle classi che non devono far

parte del test, le classi Stub si differenziano in quanto vengono create in maniera tale che forniscano

una risposta predefinita per il test in atto. Solitamente non sono in grado di rispondere diversamente

a seconda dei parametri di chiamata. Un buon esempio di classe Stub potrebbe essere un finto

servizio web che per un determinato test deve rispondere “404”.

Una classe Mock, invece, è qualcosa di più raffinato, in quanto può essere programmata per

rispondere in maniera diversa a seconda del tipo di chiamata e dei parametri. Un Mock creato per un

test specifico viene configurato in modo che si comporti in un certo modo, e si aspetta di ricevere

delle chiamate secondo una determinata specifica.

Un'altra diff erenza è data dal tipo di verifica che si vuole effettuare quando si utilizza uno o l’altro

tipo. Nel caso degli Stub la verifica viene solitamente fatta sullo stato finale della classe: dopo la

chiamata ad un servizio che risponde “404” la classe si porrà in uno stato particolare che si andrà a

controllare.

Nel caso dei Mock invece, la verifica è più orientata al comportamento. Rimanendo sullo stesso

esempio, si potrebbe controllare che il finto servizio web, impersonificato questa volta da un Mock,

venga effettivamente chiamato dalla classe in oggetto e che non riceva altre richieste. Lo stato finale

della classe in oggetto è meno importante.

Da un punto di vista del loro utilizzo, è importante notare che è estremamente più semplice creare

delle classi Stub. Esse devono infatti comportarsi solamente in un modo, non hanno stato interno e i

loro metodi forniscono sempre lo stesso risultato.

Le classi Mock sono tutt’altro che semplici da creare: esse devono mantenere uno stato interno,

collezionare informazioni sul numero e l’ordine delle chiamate ai vari metodi, informazioni da cui

dipendono i valori restituiti dai metodi esposti. Per questo motivo sono emersi dei framework che

facilitano la loro creazione ed utilizzo.

Nel mondo Java in questo momento esistono almeno 6 progetti di questo tipo: EasyMock, jMock,

Mockito, Unitils Mock, PowerMock e JMockit. L’utilizzo di un tale strumento è sicuramente

fondamentale per questo lavoro, ma il confronto delle loro caratteristiche dichiarate ha reso

evidente che le differenze non sono tali da giustificare una comparazione più accurata.

2 Stub, termine inglese che significa “matrice”, cioè l’elemento originale da cui si creano le copie 

3 Mock, termine inglese che significa “fantoccio, finto”  

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

26

Caratteristica EasyMock 

jMock Mockito UnitilsMock 

PowerMock 

JMockit 

Verifica numero invocazioni di un metodo Si Si Si No Si Si

Mock parziale Si No Si Si Si Si

Zero configurazione (inizializzazione contesto) Si Si Si Si No Si

@RunWith non necessario Si Si Si No No Si

Confronto semplificato tra oggetti VO Si No Si Si Si Si

Mock in cascata No No Si Si No Si

Supporto Mock interfacce multiple No No Si No No Si

Auto injection dei Mock  No No Si Si No Si

Mock di Enum

No No No No No SiSingle jar file No No Si No No siTabella 5 - Confronto tra Mocking framework

Appurato il fatto che tutti gli strumenti sopracitati fossero in grado di creare dei Mock a partire dalla

classe da impersonificare, il criterio utilizzato per la scelta è stato quello della curva di

apprendimento. Sono stati analizzati diversi esempi del loro utilizzo, in base ai quali è stato scelto

mockito che già dalle prime prove, si è rivelato molto intuitivo. Questo fatto può sembrare di poca

importanza, ma considerando che dovrà venire introdotto a diversi sviluppatori, questo è stato un

motivo sufficiente per far ricadere la scelta su questo prodotto. Un ulteriore punto a favore per

mockito deriva dalla quantità e “peso” delle librerie da introdurre nel flusso di lavoro. L’unicadipendenza necessaria è infatti una singola libreria da meno di 1,5Mb.

Per iniziare ad utilizzare mockito è sufficiente aggiungere al classpath l’unico jar richiesto. Dopodichè

è possibile creare Mock a partire da qualsiasi classe. Il ciclo di vita dei Mock in mockito è il seguente:

  Creare un Mock Object sulla classe o interfaccia

  Dichiarare il comportamento atteso

  Utilizzo indiretto (da parte dell’oggetto sotto verifica)

  Verifica dell’utilizzo (come è stato usato) 

Di seguito un esempio sul suo utilizzo (preso e opportunamente semplificato da uno dei casi di test

creati per O3-DPACS). In questo caso si voleva creare un Mock dell’interfaccia java.sql.DataSource.

Quando veniva richiamato il metodo getConnection, la connessione restituita doveva essere quella

configurata per quel particolare test, che veniva opportunamente inizializzata in un metodo annotato

con @Before (di JUnit).

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

27

L’oggetto sotto esame è objectUnderTest , al quale viene passato il finto DataSource. Questo viene

programmato per restituire la connessione opportunamente inizializzata quando gli verrà invocato il

metodo getConnection. Alla fine del test ci si accerta che il metodo sia stato effettivamente invocato.

DBUnit 

DbUnit è un'estensione di JUnit, ed ha come unico scopo quello di facilitare il movimento di dati

dentro e fuori dal DBMS, utilizzando dei "dataset" come astrazione dei dati. I dataset di DbUnit

possono assumere diverse forme, ma la più comune è quella di un file xml contenente i dati veri e

propri. DbUnit viene quindi utilizzato per inizializzare il database portandolo in uno stato conosciuto,

contenente esattamente quei dati che servono al test. In questo modo è possibile mantenere questi

dati in un file xml assieme alla classe di test, con conseguente versionamento. DbUnit si rivela molto

utile anche per confrontare un set di dati estratti dal database tramite il test con un dataset preciso.

Una particolarità interessante di DbUnit è che l'inserimento di un dataset nel database può essere

fatto ordinando a DbUnit di rimuovere dati preesistenti che corrispondo al dataset in questione in

modo tale da avere un set di dati sempre "pulito" su cui lavorare.

Molto comoda è anche la funzione che permette di creare un dataset a partire da dati presenti in un

dato DBMS, filtrando i dati per tabella o per valori.

Dependency Injection

La “Dependency Injection” (DI) è un pattern di programmazione nato con lo scopo di migliorare la

testabilità di sistemi software, oltre che facilitare la creazione di componenti indipendenti. Talvolta il

concetto che ne sta alla base viene riferito anche con il nome di “Inversion Of Control” (IoC). Si può

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

28

trovare anche sotto il nome di “Hollywood Principle” (“don’t call us, we’ll call you”), che ho

personalmente reinterpretato come il “principio del colloquio di lavoro” (“le faremo sapere”). 

Un componente è un aggregato di codice scritto e pensato per essere utilizzato, senza modifiche, da

un’applicazione che è fuori dal controllo di chi lo ha creato. ‘Senza modifiche’ significa che il

programma utilizzatore non ne può cambiare il codice sorgente, anche se gli è permesso dimodificarne il comportamento estendendolo nella misura prevista dal creatore del componente.

Per comprenderne il principio può essere utile accompagnare la spiegazione con un esempio

esplicativo. In questo esempio il modulo definito dalla classe GlobalConfiguration espone un metodo

che restituisce tutte le proprietà di una certa categoria.

class GlobalConfiguration...public Property[] propertiesFor(String category) {

List allProperties = finder.findAll();for (Iterator it = allProperties.iterator(); it.hasNext();) {

Property prop = (Property) it.next();if (!prop.getCategory().equals(category)) it.remove();

}

return allProperties.toArray(new Property[allProperties.size()]);

}

Sorvolando sulla qualità del codice, quello che è importante notare è che la classe utilizza un oggetto

 finder per recuperare tutte le proprietà. Per far sì che questo modulo sia indipendente dal sistema

utilizzato per la gestione delle proprietà, si può estrarre un interfaccia per il  finder che dichiari un

metodo  findAll . In questo modo la classe GlobalConfiguration può ignorare l’attuale

implementazione del finder .

public interface PropertyFinder {

List findAll();

}

A questo punto però, da qualche parte si deve pur inizializzare la variabile finder con la sua

implementazione, ad esempio nel costruttore.

private PropertyFinder finder;

public GlobalConfiguration() {

finder = new TextFileGlobalConfiguration("configuration.txt");

}

Questa implementazione del PropertyFinder  legge le proprietà da un file di testo. Ma cosa succede se

questo modulo viene utilizzato da un’applicazione che però vuole utilizzare un database al posto del

file di testo? Siccome GlobalConfiguration utilizza l’interfaccia PropertyFinder , è sufficiente crearne

una seconda implementazione che legga i dati dal DBMS. Rimane però il problema che il finder viene

inizializzato nel costruttore; è stata infatti creata una dipendenza verso TextFileGlobalConfiguration.

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

29

Dal diagramma delle classi si vede che GlobalConfiguration  è dipendente sia dall’interfaccia che dalla

sua implementazione. Per ovviare a questo problema e fare in modo che l’unica dipendenza sia

quella verso l’interfaccia, si utilizza la tecnica della Dependency Injection. 

L’idea di base è avere un oggetto separato che si assume la responsabilità di assegnare la corretta

implementazione dell’interfaccia in GlobalConfiguration.

Il risultato è quello che nei manuali di design pattern viene chiamato “plugin pattern”. Ora dovrebbe

anche essere chiaro anche il motivo del nome “Hollywood Principle” (don’t call us, we’ll call you). La

classe GlobalConfiguration  è ‘passiva’ rispetto alle sue dipendenze, si aspetta che qualcun altro si

prenda la responsabilità di inizializzare un implementazione adeguata del PropertyFinder  e che gli

venga notificato. Questo è il principio di base, poi ci sono diverse interpretazioni che differiscono per

il modo in cui le dipendenze vengono soddisfatte. Tipico è il caso delle dipendenze passate come

parametri nel costruttore. Altre volte si prevede un implementazione di default, modificabile tramite

setter (questo è il metodo più utilizzato nel lavoro di refactoring eseguito su parte di O3-DPACS perrenderlo testabile).

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

30

Sviluppo

Per la creazione dei casi di test per O3-DPACS è stato seguito un determinato ordine. Le prime classiche sono state controllate sono quelle che dall’analisi sono risultate idonee per essere sottoposte a

test di unità logiche. Va sottolineato il fatto che la creazione di questo tipo di test fatta a posteriori ha

poca valenza se il fine è scovare eventuali errori. La maggior parte del codice che è stato sottoposto

a questo controllo esiste da diversi anni e viene regolarmente usato senza riscontrare problemi. Il

momento della creazione degli unit-test, invece, dovrebbe essere contestuale alla creazione delle

singole classi. Lo scopo è coprire con dei test quella parte di codice di più “basso livello”, cercando di

mettere in difficoltà il sistema con i dati più critici. Il motivo per il quale sono stati comunque creati

questi casi di test di unità, è per identificare le difficoltà comuni e proporre delle soluzioni. Inoltre,

con la creazione di buon numero di casi, sarà possibile verificare che il processo di automazione della

loro esecuzioni funzioni correttamente.

Lo sviluppo è proseguito con la verifica di tutto ciò che comunica con un DBMS, cercando le soluzioni

migliori per i diversi casi (query dirette via JDBC, chiamate alle Stored Procedure, accesso ai dati

tramite JPA). Nella fase successiva sono state prese in considerazione le classi che interagiscono con

più unità, creando degli appositi test di integrazione. Alla fine si è arrivati ai test funzionali passando

per i servizi Dicom ed Hl7 del PACS (MBean ed EJB).

Creazione di unit test 

Per questa tipologia, un buon punto di partenza è stato il package it.units.htl.dpacs.helpers. Al suo

interno vi si trovano una serie di classi di utilità che offrono funzioni che ben si prestano ad essere

verificate in isolamento, analizzando l’output a seconda degli input forniti.

 Anonimizer

La prima classe analizzata e testata è la it.units.htl.dpacs.helpers.Anonimizer. Questa classe espone

dei metodi che accettano un dataset Dicom, un oggetto che contiene dei metadati riguardanti un file

Dicom (dati anagrafici del paziente, dettagli degli esami, etc.). Il risultato è lo stesso dataset, ma

spogliato di alcuni dati per impedire il riconoscimento del paziente.

La creazione del test con JUnit in questo caso è banale. Quello su cui è stato possibile riflettere è

l’insieme dei dati da utilizzare. Le variabili in ingresso sono numerose, e sono date dai campi deldataset che devono essere anonimizzati. Per ogni variabile però, si individuano solamente due classi

di equivalenza: variabile valorizzata e variabile non valorizzata.

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

31

Variabili Classi equivalenza

Dati paziente null valorizzato

Nome null valorizzato

Cognome null valorizzato

Id null valorizzato

… null valorizzato

Dati medico curante

Nome null valorizzato

Cognome null valorizzato

… null valorizzato

In base a queste considerazioni, per questa classe è stato sufficiente creare due casi per ogni

metodo.

Si potrebbe pensare che due classi di equivalenza siano poche, ma questa considerazione nasce

dall’analisi diretta del codice della classe Anonimizer. È possibile vedere come i valori delle variabili

non vengano mai lette, ma solamente sostituite con dei valori standard, previo controllo sul loro

essere null o meno. Quando un test viene creato esplorando il codice sorgente dell’oggett o

sottoposto a verifica, si dice che si sta eseguendo del “white box” testing. Questo si differenzia dal

metodo di “black box” testing che non prevede che chi scrive i test abbia conoscenza

dell’implementazione dell’oggetto. Il white-box testing ha il vantaggio che permette la copertura di

una maggiore, se non totale, porzione di codice. Lo svantaggio sta nel fatto che il tester di solito è lo

stesso che ha sviluppato la classe in esame, e per questo è meno obbiettivo.

DateHelper

La classe DateHelper fornisce un metodo getFirstUsefulDate che a partire da una stringa, restituiscedata e ora corrispondente. Se la combinazione di data e ora rappresenta un instante nel passato,

allora restituisce la prima occorrenza di quell’ora nel futuro. Questo metodo viene utilizzato per la

configurazione di più servizi, in particolare per far iniziare l’esecuzione di diversi task temporizzati. 

In questo caso le classi di equivalenza sono più interessanti, e vengono riportate nella seguente

tabella con il rispettivo risultato aspettato.

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

32

Input D,T (data e ora) Expected Output (Date)

Null Null

Formato di D,T non valido Null

D,T > now() Data e ora corrispondente a D,T

D < today(), T > now() Data del giorno corrente, ora pari a T

D,T < now() Data del giorno seguente, ora pari a T

Il risultato di questa tabella è la classe DateHelperTest con 5 metodi, uno per caso di test.

DateTimeRange

Con la DateTimeRange si rimane sugli strumenti per la manipolazione di date. È interessante notare

come per questa classe fosse già previsto un test nel sistema preesistente. Questo è uno dei pochi

casi in cui è stato esplicitamente definito una unit-test utilizzando l’unico sistema che era previsto,

quello degli script-test (istruzioni testuali, esecuzione manuale).

DateTimeRange nasce dalla necessità di dover gestire intervalli di date in maniera precisa,

prevedendo molte opzioni. Viene utilizzata per supportare l’interrogazione delle liste di lavoro dato

un certo intervallo di tempo. La complicazione arriva proprio dal numero di parametri e dai loro

valori possibili.

Questa classe è più complessa delle precedenti, ma è completamente isolata dal resto

dell’applicazione, per questo motivo viene riportata come esempio significativo di test di unità

realizzato sul sistema.

Il funzionamento prevede che ad un’istanza vengano configurati gli estremi degli intervalli definiti dadue estremi “sinistri” (data inizio, ora inizio) e due “destri” (data fine, ora fine). È possibile impostare

da uno a tutti e quattro i parametri per ottenere risultati differenti. Dopo aver inizializzato gli estremi

voluti, è possibile ottenere la data e ora (in formato java.util.Date) del limite destro e del limite

sinistro dell’intervallo impostato. L’analisi dei possibili valori ha portato alla seguente tabella, che

copre tutti i casi possibili.

DATE TIME Expected output

FROM TO FROM TO FROM TO

X Y J K x.j <= DATA <= y.kX Y J - x.j <= DATA <= Y

X Y - K X <= DATA <= y.kX Y - - X <= DATA <= Y

- Y J K - <= DATA <= y.k- Y J - - <= DATA <= Y- Y - K - <= DATA <= y.k- Y - / - <= DATA <= Y

X - J K x.j <= DATA <= -X - J - x.j <= DATA <= -X - - K X <= DATA <= -X - - - X <= DATA <= -

- - J K J <= DATA <= K- - J - J <= DATA <= -

- - - K - <= DATA <= K- - - - - <= DATA <= -

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

33

La metà sinistra della tabella copre tutti gli input possibili, mentre sulla sinistra viene riportato il

risultato aspettato per ogni caso. La X e la Y rappresentano delle date, mentre la J e la K

rappresentano delle ore. Le celle degli input contenenti il simbolo ‘–‘ significano che l’estremo

corrispondente non è impostato. Nelle celle dell’output invece significa che il limite è indefinito. Da

questa tabella è stato creata una classe di test contenente tutti i 16 casi significativi individuati.

FileHasher

Ci sono casi in cui non è possibile creare lo unit-test di una classe senza modificarne il codice. Questo

è un problema che si presenta frequentemente in O3-DPACS, come in tutti i programmi scritti senza

avere in mente questo obbiettivo. La classe FileHasher ne è un buon esempio.

Questa semplice classe computa l’hash di un file passato come parametro assieme al nome

dell’algoritmo da utilizzare. Al suo interno però va ad interrogare un gestore di proprietà del sistema

per conoscere la dimensione del buffer da utilizzare. Questa dipendenza non consente di testare la

funzionalità di hash poiché, preso al di fuori del contesto in cui si aspetta di essere eseguita, il gestore

di proprietà non funziona (in questo caso è un MBean che interroga un DBMS).

Il refactoring di questa come di altre classi, ha come vincolo fondamentale quello di mantenere

laddove possibile, l’interfaccia della classe modificata invariata. Questo requisito è necessario per

assicurarsi che gli utilizzatori sparsi nel resto dell’applicazione, non debbano a loro volta essere

intaccati, rimanendo sicuri che tutto continuerà a funzionare.

Analizzando la classe sotto esame si vede come il gestore di proprietà viene richiamato all’interno del

metodo doHash. Per non modificare questo comportamento (giusto o sbagliato che sia), è stata

aggiunta una proprietà a livello di classe contenente il valore della dimensione del buffer, ed un

relativo metodo setter .

Nella funzione doHash è stato aggiunto un

controllo in modo che il gestore venga interrogato

solamente se il setter  non è stato esplicitamente

chiamato.

A questo punto è stato possibile creare il test, che

dato un file di riferimento, verifica che l’hash

restituito dal metodo sia corretto tenendo conto

dell’algoritmo utilizzato. Gli algoritmi di hash

testati sono SHA-1, SHA-256 e MD5. Per la

realizzazione è stata sfruttata la funzionalità di

JUnit per rieseguire lo stesso test-case più volte variandone i parametri. Il parametro variato è

l’algoritmo, mantenendo fisso il file di riferimento; ovviamente anche il risultato aspettato varia con

l’algoritmo, quindi i parametri passati al test sono la coppia algoritmo-risultato atteso.

Figura 1 - diagramma di flusso del metodo doHashmodificato 

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

34

UidGenerator

In Dicom, ogni immagine è univocamente identificata da un UID (Universal ID), formato da una serie

di caratteri numerici separati dal carettere punto. Il valore finale è la composizione di più parti:

  Root id: identificativo univoco dell’organizzazione che crea l’uid delle istanze

  Study Instance UID: id relativo dello studio (esame)

  Series Instance UID: id relativo della serie (ogni studio può avere n serie)

  SOP Instance UID: id relativo della singola immagine.

Esempio di Sop Instance UID:

La classe UidGenerator viene utilizzata per generare uid con la

root id assegnata ad O3-Enterprise. La cosa interessante è che

data un’istanza, è possibile generare degli UID per nuovi studi,

serie ed istanze. Qui non ci sono input in base ai quali cambia il

risultato, ma è lo stato interno della classe che cambia in base ai

metodi invocati (senza parametri) ciascuno dei quali restituisce

l’uid del tipo richiesto. Di conseguenza l’obbiettivo del test non sarà quello di verificare il risultato in

base ai parametri di ingresso, ma sarà quello di verificare l’output ad ogni cambiamento di stato.

Lo stato di ogni istanza è dato dalla terna UID dello studio (X), UID della serie (Y) e UID dell’istanza (Z).

È possibile modellizzare la classe come una macchina a stati da cui è possibile ricavare la seguente

tabella delle transizioni:

T1 T2 T3 T4

Stato inizale X;Y;Z X;Y;Z X;Y;Z X;Y;Z

Evento getNewStudy getNewSerie getNewInstance reset

Effetto X++ Y++ Z++ X = newStudyUid();

Y = newSeriesUid();

Z = 1;

Stato finale X+1;Y;Z X;Y+1;Z X;Y;Z+1 X’;Y’;Z’ 

Nella teoria dei test si parla di “0-switch coverage” quando i test creati sono pari al numero di

transizioni. In questo caso i casi sarebbero 4. Fermo restando che la copertura totale di una classe di

questo tipo è impossibile (esistono infiniti stati), per aumentare la copertura con i test, è necessario

provare un numero maggiore di combinazioni stato-transizione. Lo “1-switch coverage” prevede che

vengano esplorate le combinazioni scendendo di un livello nell’albero delle combinazioni, con

conseguente incremento esponenziale dei casi di test.

UidGenerator

+ getNewStudyUid() : String+ getNewSeriesUid() : String+ getNewInstanceUid() : String+ reset ()

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

35

Figura 2 - 1-switch coverage per UidGenerator

L’albero in figura rappresenta tutte le diramazioni possibili fino al secondo livello. I cerchi rossi

indicano gli stati e transazioni appartenenti allo “0-switch”, mentre aggiungendo i cerchi rossi si

raggiunge lo “1-switch coverage”, con un totale di 16 casi di test. Ciascun test parte dallo stato

rappresentato dalla radice e arriva fino alla foglia più esterna, coprendo tutte le transizioni previste

dal percorso.

KosBuilder

Fra tutti gli unit-test creati, l’ultimo caso che viene proposto è stato scelto perché si presta bene

all’introduzione di un problema comune in molte parti del codice di O3-DPACS. La classe KosBuilder

ha il compito di costruire un file dicom particolare detto “KOS” (Key Object Selection), che al suo

interno non contiene immagini ma solamente riferimenti a istanze di altri file dicom. Il kos viene

creato in base ai parametri di ingresso, che in questo caso è un oggetto KosMetaInfo, contenente

tutti i dati necessari per ottenere un file kos.

Il problema nel testare questa come altre classi, è dato dal fatto che il test dovrebbe verificare che il

file generato contenga i dati corretti secondo quanto passato in ingresso. Questa operazione può

essere vista come una sorta di conversione dal tipo A al tipo B. La verifica d ovrebbe dire se l’istanza

di A “equivale” all’istanza di B. Per fare questo è quindi utile creare dei comparatori che siano in

grado di confrontare istanze di tipo diverso tra loro.

Per il caso di KosBuilder è stata creata una classe KosComparator costruita in maniera tale da

verificare che i dati provenienti dal KosMetaInfo siano stati correttamente riportati nel relativo file

KOS. A questo punto per la scrittura del test, ci si riconduce alla procedura già vista dell’analisi delle

variabili di ingresso (in questo caso le proprietà del KosMetaInfo) individuandone le classi di

equivalenza e scrivere i casi di test di conseguenza.

Database Testing (jdbc, stored procedure, jpa)

Test di classi DAO

In O3-DPACS esiste un certo numero di classi DAO utilizzate per l’accesso ai dati salvati nel DBMS.Tutte queste classi hanno una struttura simile tra loro ed utilizzano query SQL standard tramite i

connettori JDBC. Espongono una serie di metodi pubblici che astraggono prevalentemente delle

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

36

SELECT ed in minor numero degli UPDATE. Ciascun metodo ottiene una connessione da un

DataSource, acquisito a sua volta tramite JNDI lookup.

Queste classi si aspettano quindi che a runtime ci sia un contesto JNDI in cui vi sia registrato un

DataSource dal quale recuperare le connessioni al DBMS, ma tutto ciò in un unit-test non è possibile.

È necessario modificare queste classi facendo in modo che l’acquisizione di una connessione possaavvenire anche in un modo differente, mantenendo al contempo il sistema esistente.

Per fare questo le classi DAO sono state modificate aggiungendo un costruttore (oltre a quello

preesistente senza parametri) nel quale viene passato un DataSource che la classe deve utilizzare per

ottenere le connessioni. In questo modo il comportamento originale non è stato intaccato ma per

effettuare i test sarà possibile fornire un DataSource configurato appropriatamente.

Per mostrare il risultato viene riportato il caso della classe UserManager.

Il metodo privato getConnection veniva richiamato da ogni metodo pubblico per ottenere una

connessione dal DataSource. Nel refactoring il DataSource è una proprietà privata che viene

inizializzata nel costruttore.

Avendo isolato le classi DAO dal resto del sistema, contesto JNDI incluso, rendendole testabili, resta il

problema di dover fornire un DataSource ad ogni classe prima di verificarne i vari metodi.

A questo scopo è stata scritta un’apposita classe astratta che se estesa, facilita la creazione di

DataSource validi che vengono poi forniti alle classi sotto test. Se utilizzata, automaticamente ciascun

caso di test viene eseguito N volte, dove N è il numero di DBMS su cui si vuole testare. Ad ogni

esecuzione, il caso verrà testato su una connessione verso un DBMS diverso.

Tutto ciò è possibile specificando nella classe astratta (JDBCTestCase) che per eseguire i test venga

utilizzato il motore di JUnit per test parametrici.

In questo modo tutti i metodi contrassegnati dall’annotazione @Test verranno eseguiti N volte,

ciascuna avente un JDBCConnectionMetadata diverso. Quest’ultima classe è un contenitore di

parametri utilizzati per la connessione al DBMS (driver, user, password, url jdbc, schema, vendor).

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

37

L’inizializzazione del DataSource avviene in un metodo di JDBCTestCase annotato con @Before. In

realtà non viene creato un vero e proprio DataSource, ma viene utilizzato un Mock.

Oltre alla connessione JDBC, ne viene creata anche una seconda dedicata a DBUnit. Il risultato è che

qualsiasi classe estenda JDBCTestCase, avrà automaticamente a disposizione un DataSource valido da

poter passare all’istanza sotto test, ed una connessione DBUnit per preparare il DBMS al test. 

Per utilizzare questa classe è sufficiente estenderla, dopodiché è possibile utilizzare il DataSource e la

connessione per DBUnit, come è stato fatto nel caso di UserManagerTest:

Con questa tecnica è stato possibile testare diverse classi DAO, evitando di dover ogni volta creare

una connessione e un caso diverso per ogni DBMS supportato.

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

38

Stored Procedure

L’approccio per l’accesso ai dati più diffuso non è tramite l’utilizzo delle classi DAO ma tramite

chiamate a Stored Procedure sparse un po’ ovunque nella logica di O3-DPACS. Sebbene la

valutazione di questa scelta non sia oggetto di questo lavoro, lo è sicuramente il problema di come

testare le Stored Procedure. Queste vengono inserite in svariati punti di metodi il cui scopo principale

non è quello della comunicazione con il database; per questo motivo non si andrà a testare quei

metodi ma si andrà a creare una batteria di unit-test, ciascuno dei quali avente il compito di

verificare il corretto funzionamento di una stored-procedure.

La totalità delle stored procedure definite in O3-DPACS sono state suddivise in categorie in base al

tipo di entità su cui vanno ad operare e il tipo di operazione SQL (INSERT, UPDATE, DELETE, SELECT).Per l’elenco completo e relativa classificazione si faccia riferimento alla tabella in appendice.

Come per i test delle classi DAO, anche in questo caso è stata creata una classe astratta che si occupa

della maggior parte dei dettagli sulla creazione della connessione, molto simile alla JDBCTestCase.

Tutte le classi risultanti dalla categorizzazione delle stored-procedure estendono

StoredProcedureTestCase.

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

39

I test delle stored-procedure (SP) si differenziano da quelli “semplici” che utilizzano JDBC con le

operazioni SQL tradizionali in quanto la sintassi delle chiamate alle SP cambia a seconda del DBMS su

cui si esegue la procedura.

if (isOracle) {callableStatement = connection.prepareCall("{call getPatientInfo(?,?)}");

callableStatement.registerOutParameter(2, OracleTypes.CURSOR);

callableStatement.execute();

resultSet = (ResultSet) callableStatement.getObject(5);} else if(isMySql) {

callableStatement = cononnection.prepareCall("{call getPatientInfo(?)}");

resultSet = callableStatement.getResultSet();}

Per ovviare a questo problema è stata creata una classe astratta StoredProcedure che si comporta da

involucro per le CallableStatement (classe Java utilizzato per eseguire le stored procedure via JDBC),

le cui implementazioni per MySQL ed Oracle si occupano di utilizzare la sintassi corretta. La creazionedi oggetti StoredProcedure avviene attraverso l’utilizzo di una “Factory”, alla quale viene passata la

connessione e restituisce l’implementazione corretta di StoredProcedure per il DBMS in uso. 

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

40

StoredProcedureFactory spf = new StoredProcedureFactory(connection);storedProcedure = spf.getStoredProcedure();

callableStatement = storedProcedure.prepareCall("getPatientInfo");

callableStatement.execute();resultSet = storedProcedure.getResultSet();

Il risultato di questa infrastruttura è che per testare una stored-procedure è sufficiente creare una

classe che estenda la classe astratta StoredProcedureTestCase, e almeno un metodo annotato con

@Test in cui è possibile utilizzare un’istanza di StoredProcedure già opportunamente inizializzata.

Ciasuno di questi metodi @Test verrà eseguito una volta per ogni tipo di DBMS configurato.

JPA (Hibernate)

Le interfacce JPA (Java Persistence Api) e la loro implementazione Hibernate, non sono un’esclusiva

di Java Enterprise, anche se la maggioranza degli utilizzatori sono applicazioni web che vengono

eseguite in web container come Tomcat o JBoss. Tuttavia è possibile sfruttare questa tecnologia

anche all'infuori di un container. È quindi possibile creare test per quello strato dell'applicazione che

sfrutta JPA come astrazione della base dati.

Per riuscire nell'opera di testare le classi che utilizzano direttamente le API di JPA, è necessario

configurare l'ambiente in cui esse andranno eseguite. In particolare le API di JPA prevedono che nelclasspath vi sia un file di configurazione persistence.xml contenuta nella cartella META-INF, con

all'interno la definizione delle cosiddette persistenceUnit, ciascuna delle quali descrive un set di classi

che devono essere considerate come entità persistenti (classi che astraggono tabelle del database)

ed una serie di configurazioni necessarie per creare connessioni al database.

Per poter testare le classi e i metodi che utilizzano JPA, sarà quindi sufficiente creare una

'persistence-unit' contenente tutte le informazioni necessarie per connettersi al database di test.

Dalla classe di test sarà così possibile ottenere un'istanza di EntityManager (principale interfaccia

messa a disposizione da JPA attraverso la quale è possibile interagire con le "entità persistenti") ed

effettuare tutte quelle operazioni che vengono normalmente fatte all'interno dei metodi delle classi

che si vogliono testare. Rimane però un problema tipico delle applicazioni enterprise: nelle classi da

testare, l'EntityManager viene ottenuto praticamente sempre tramite lookup jndi. Portando queste

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

41

classi fuori dal container di JBoss dove normalmente vengono eseguite, il lookup fallisce e si deve

scegliere una fra le varie soluzioni studiate.

In questo caso particolare si è scelto di arricchire la classe da testare aggiungendo un metodo

setEntityManager() con il solo scopo di permettere l’assegnazione di un EntityManager creato

appositamente per test, come avveniva per i DataSource.

Creazione dei test di integrazione ed MBean

I test di integrazione coinvolgono classi che hanno numerose dipendenze verso altre classi. La

situazione ideale vorrebbe che queste classi “secondarie” siano completamente isolate dal resto

dell’applicazione e ignare del loro utilizzatore (candidate ideali per unit-test). Purtroppo nella realtà

ciò non avviene, rendendo molto difficile la verifica della classe che al suo interno fa riferimento a

numerose altre classi. Se queste ultime a loro volta dipendono da altre classi, allora il test non può

che essere fatto sull’ambiente finale, dove l’applicazione viene eseguita solitamente. Ci sono casi in

cui è più conveniente eseguire i test in questo modo, ma in altri è possibile riportarsi ad una

situazione favorevole alla creazione di test di porzioni di applicazione, passando attraverso un

processo di refactoring. Questo lavoro può essere anche difficile, ma se l’obbiettivo viene raggiunto,

allora i vantaggi ripagano sicuramente dello sforzo.

Come esempio di test di integrazione reso possibile grazie al refactoring, viene riportato il caso della

classe StoragePerformer. Di seguito ne viene riportato il workflow:

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

42

Il test di integrazione si basa sull'ipotesi che le singole componenti ivi usate siano già state testate nei

loro rispettivi unit-test (Compression e FileHasher). In questo test invece si testeranno le seguentisituazioni per coprire i vari percorsi:

  Test case 1: salvataggio in directory non esistente, con conseguente creazione del path (il

salvataggio in directory già esistente è considerabile come un sottoinsieme di questo caso)

  Test case 2: l'hash viene calcolato e restituito col metodo getHash

  Test case 3: il file viene compresso se richiesto

Problemi e soluzioni adottate:

  Dipendenza dalla classe Compression: l’istanza veniva recuperata da un MBean nel

costruttore; questo perché l’istanza restituita è già stata configurata correttamente inprecedenza in altri punti dell’applicazione. Per test, è stato aggiunto un costruttore a

StorageServer che accetta un’istanza di Compression. 

  Dipendenza dalla classe FileHasher: l’istanza viene creata all’interno de l metodo che salva il

file su disco, ma i parametri della sua configurazione vengono ricavati dal MBean di

DicomServer. Per mantenere invariato questo comportamento è stato creato un Mock del

DicomServerMBean registrato in un MBeanServer di test.

  L'integrazione con il filesystem rende necessaria l’esistenza di una directory disponibile sul

filesystem del sistema di test. Una possibilità è quella di prevedere una directory temporanea

dedicata sul sistema di test. Un’altra possibilità, che è quella adottata, vuole che si utilizzi ladirectory corrente. Questa soluzione è stata preferita in quanto ha un impatto minore sul

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

43

sistema di test, e non ha bisogno di configurazioni. Al termine del test la cartella temporanea

viene rimossa.

Uno dei principali problemi che si sono presentati in questa classe nasce dal fatto che diverse

configurazioni vengono prese da diversi MBean registrati in un MBeanServer (tecnologia JMX).

Questo approccio si ritrova in numerose classi, per questo motivo si è cercata una soluzione chepotesse garantire alle classi sotto esame di trovare gli MBean richiesti, ottenendo dei parametri di

configurazione opportunamente settati caso per caso.

Gli MBean utilizzati in O3-DPACS sono:

  DicomServerMBean

  HL7ServerMBean

  StorageSCPMBean

  QueryRetrieveSCPMBean

  WorklistServiceMBean

  StudiesVerifierMBean

  MPPSSCPMBean

  CompressionSCPMBean

  ImageMaskingSCPMBean

  ForwarderServiceMBean

  AuditLogServiceMBean

Questi MBean vengono utilizzati in molteplici punti dell’applicazione per recuperare i parametri di

configurazioni per i vari servizi Dicom (Storage, Query/Retrieve, Worklist), HL7, verifica degli studi,

etc.

Per ciascuno di essi è possibile creare un Mock, che viene registrato su un MBeanServer fatto partire

prima di ogni test e fermato al termine. Per semplificare questo processo si può creare anche qui una

classe astratta per JUnit.

Le classi sotto esame sono le varie StoragePerformer , StorageServer , StorageSCU etc. Queste classi siaspettano di trovare i vari MBean registrati nell’MBeanServer , dai quali ottenere i parametri di

configurazione. MBeanTestCase crea un MBeanServer apposito dove vengono registrati i Mock degli

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

44

MBean, e vengono resi recuperabili facilmente con i vari getNomeMBean. In questo modo le classi di

test che estendono MBeanTestCase per preparare l’ambiente possono prendere il Mock dell’MBean

di interesse, valorizzarne i vari parametri ed essere sicuri che la classe sotto test verrà eseguita

leggendo i parametri configurati appositamente.

Test dei servizi

Tra i vari servizi di O3-DPACS, quello più importante è probabilmente il servizio di Storage. Questo

viene utilizzato alla ricezione di immagini diagnostiche tramite il protocollo dicom. I dettagli sulla

comunicazione tra client e server vengono delegati ad una libreria java apposita “dcm4che”. Questa

libreria astrae i dettagli sulla creazione del server ed espone un interfaccia a callback dove

l’applicazione può registrarsi per gestire determinate transazioni. In dicom l’invio di immagini avviene

tramite la transazione “C-STORE”; O3-DPACS è programmato in maniera tale che alla ricezione di un

immagine venga richiamato, tramite callback di dcm4che, il metodo doCStore della classe

StorageServer .

Il test di questo metodo consente di verificare la logica di business relativa alla ricezione di file dicom.

Normalmente per effettuare dei test è necessario avviare l’applicazione al completo. L’obbietivo è

quindi evitare tutto ciò isolando il più possibile la classe in esame.

Il primo passo è identificare le dipendenze. Dall’analisi della classe sono state evidenziate le seguenti

dipendenze:

1.   Anonimizer : aggiunto ai parametri del costruttore

2.  GlobalConfigurationLoader : vedi nota-1

3.  StorageSCPMbean: già presente nei parametri del costruttore

4.  DicomStorageDealerLocal : aggiunto ai parametri del costruttore

5.  CompressionSCP: vedi nota-2

6.  DicomStorageDealer : aggiunto ai parametri del costruttore

7.  ImageMaskingSCP: vedi nota-3

8.  DicomDbDealer : aggiunto ai parametri del costruttore

Nota-1

GlobalConfigurationLoader  è una classe che espone un metodo statico getConfigParam per

recuperare dei parametri di configurazione dal DBMS. Per rendere StorageServer  indipendente da

questa classe e quindi dalla presenza del DBMS, è stato effettuato un refactoring di

GlobalConfigurationLoader : è stata creata un’interfaccia “ConfigurationLoader”  la quale espone ilmetodo getConfigParam, e GlobalConfigurationLoader  è diventata una implementazione che

recupera i dati dal DBMS. Per il test di StorageServer , viene passato un Mock dell’interfaccia. 

Nota-2

Di CompressionSCP viene richiamato soltanto il metodo statico getCompressionTransferSyntax , che a

sua volta richiama un metodo di DicomDbDealer . È stata quindi eliminata questa dipendenza a favore

della chiamata diretta a DicomDbDealer.

Nota-3

Di ImageMaskingSCP vengono usati i metodi isImageElaborationEnabled, getMaskTags, getMasks. I

primi due richiamano i metodi di DicomDbDealer , quindi sono stati eliminati in favore a chiamate

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

45

dirette a quest’ultimo. Il terzo metodo è un metodo statico al cui interno non ci sono ulteriori

dipendenze, quindi è stato mantenuto.

Il costruttore della classe StorageServer originale ha 1 solo parametro. Quello creato appositamente

per consentirne il test ne ha 5. Non sono stati riscontrati casi con un numero ancora maggiore di

dipendenze, per questo motivo si è ritenuto che esplicitare questi parametri nel costruttore sia unasoluzione accettabile, motivazione avvalorata anche dal fatto che rende più evidente quali sono le

oggetti utilizzati di cui si deve tener conto.

In questo modo è stato ottenuto un livello di isolamento sufficiente per poter sottoporre la classe a

test all’infuori del container J2EE. 

Per testare il metodo doCStore è necessario creare un server dicom apposito sfruttando le librerie

dcm4che, e registrare l’istanza di StorageServer  quale “ascoltatore” (listener ) per transazioni di tipo

“C-STORE”. A questo punto è possibile inviare un’immagine dicom al server attravers o una seconda

classe creata appositamente.

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

46

Il test degli altri servizi dicom segue la stessa struttura, quello che cambia è il tipo di transazione

effettuata dal DicomClient e l’istanza della classe sotto esame che viene registrata nel DicomServer

come classe da chiamare alla ricezione di quella determinata operazione.

Lo stesso approccio è da utilizzarsi anche per i servizi HL7. Cambiano le librerie, ma il principio di

utilizzo lo stesso. Anche queste librerie prevedono la creazione di un Server HL7 al quale viene

registrata la classe che si occupa di gestire i vari messaggi. Le classi da testare hanno lo stesso nome

della transazione, quindi per i messaggi ADT^A08 (aggiornamento anagrafica paziente), si testa la

classe ADTA08 tramite la classe di test ADTA08Test, la quale crea il client e server HL7 e gestisce

l’invio del messaggio e successiva verifica dei risultati. 

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

47

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

48

 Automazione

Per l’automazione dell’esecuzione dei test è stato scelto di usare Jenkins. Questo è uno dei server di“Continuous Integration” (CI) esistenti e tra i più utilizzati; “l’integrazione continua” è una pratica di

sviluppo del software dove le modifiche al codice vengono integrate frequentemente. Ad ogni

integrazione dovrebbe seguire un build automatico (compilazione e “impacchettamento” dei vari jar,

war, ear), eseguito su un server apposito, verificato con l’esecuzione di tutti i test definiti per il

progetto. I requisiti per mettere in pratica questa metodologia sono:

1.  codice su repository (SVN, CVS, git) 

2.  codice con commit frequenti sul trunk (commit di ogni issue) 

3.  commit di codice sempre "funzionante" 

4.  tool di building automatico (ant, maven, make) 5.  server di CI (Jenkins, Cruise Control, Apache Continuum, etc.) 

Il processo di sviluppo di O3-DPACS soddisfa pienamente i primi tre punti. Il quarto punto è

parzialmente implementato (esistono e vengono utilizzati gli script di build dei vari pacchetti, che

va integrato con uno script per la compilazione dei test e della loro esecuzione). Nel quinto

punto entra in gioco Jenkins.

Script di build ed esecuzione automatici

O3-DPACS utilizza script Ant per la compilazione e impacchettamento dei sorgenti. Di conseguenza è

stato utilizzato anche per la compilazione delle nuove classi di test. Il task per la loro compilazione èstato integrato nello script preesistente, affiancandolo a quelli originali.

Per l’esecuzione dei test invece, è stato creato uno script ant apposito “Test Runner.xml” con i

seguenti task:

Il task “Compile and run” è un task che dichiara solo dipendenze e fa scattare gli altri test nell’ordine

indicato nel grafico.

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

49

Il primo task chiamato è “Prepare for tests” che copia i file di configurazione necessari ai test (dati di

test, file xml, e file di proprietà per le connessioni ai DBMS). “Compile core tests” compila i sorgenti

dei test, ma non prima di aver compilato i sorgenti dell’applicazione. Infine lancia il task che esegue

tutti i test JUnit presenti nei sorgenti.

Utilizzo di Jenkins

L’obbiettivo finale è riuscire a configurare il server di CI in maniera tale che ad ogni commit sul trunk

dell’SVN, vengano automaticamente scaricati gli ultimi sorgenti, compilati, ed eseguiti tutti i test,

creando un report visualizzabile da interfaccia web.

Jenkins viene distribuito come un singolo file “war” (applicazione web Java Enterprise), che può

essere eseguito all’interno di un container J2EE, ma può essere anche eseguito come applicazione

“stand-alone” in quanto nella distribuzione è già compreso un mini container J2EE. Ovviamente

questo pone delle limitazioni alle possibilità di configurazione, ma per il momento è più che

sufficiente. Per far partire l’applicazione è sufficiente eseguire il comando: 

java –jar jenkins.war

In questo modo viene avviato un server web con l’applicazione al suo interno. La configurazione

avviene completamente tramite interfaccia web. I passi necessari per automatizzare il build e i test di

O3-DPACS sono:

  Creare un “Job” Jenkins per O3-DPACS

  Configurare il repository SVN in modo tale che prenda i sorgenti dal trunk del progetto

  Specificare gli script ant per il build dell’applicazione 

  Aggiungere il secondo script ant per l’esecuzione dei test Il “job” così configurato è in grado di compilare applicazione e test, ed eseguire questi ultimi. Per fare

in modo che questo job venga eseguito ad ogni commit sul trunk, è necessario aggiungere un poll sul

repository SVN che controlli periodicamente se ci sono modifiche dall’ultimo controllo. 

Per ottenere il report dei test è stato necessario modificare lo script “Test Runner” affinchè generi un

report XML, dopodiché da Jenkins è sufficiente indicare la directory dove vengono salvati i report per

fare in modo che questi vengano caricati nell’interfaccia web. 

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

50

Conclusioni

Risultati ottenuti

Il progetto O3-DPACS è stato arricchito da una serie di strumenti che consentono e facilitano la

scrittura di unit-test per diverse componenti dell’applicazione che altrimenti richiederebbero

l’esecuzione dell’intera applicazione in un ambiente completamente configurato. Le componenti

principali sono:

  Classi DAO

  Stored procedure

  Classi che accedono al DBMS tramite Hibernate

  Classi che utilizzano gli MBean di JMX

  Servizi Dicom e HL7

Sono inoltre stati affrontati gli ostacoli più ricorrenti emersi nel tentativo di testare classi con

dipendenze, analizzando i vari problemi e individuando soluzioni comuni come il refactoring delle

classi sfruttando il pattern di programmazione della “Dependency Injection”. Ci si è avvalsi di ulteriori

tecniche per aumentare il disaccoppiamento tra moduli ricorrendo a classi Stub e Mock e relativi

framework.

Affianco all’attuale processo di testing del software di O3-Enteprise, sono stati integrati gli unit-test

con l’introduzione di JUnit come framework di base e sono stati creati dei test veri e propri su parti

eterogenee del codice. Nel farlo, sono state utilizzate tecniche di software testing quali ilpartizionamento delle variabili di input in classi di equivalenza e copertura “intelligente” del codice

tramite esplorazione dei grafi.

È stata infine proposta una soluzione funzionante per adottare la tecnica della “Continuous

Integration” che permette l’esecuzione automatica dei test ad ogni modifica del codice versionato su

SVN.

Confronto

Dell’insieme di tutti i test creati, soltanto alcuni possono essere considerati equivalenti a dei test

preesistenti. Perciò solo di questi è stato possibile fare un confronto diretto in termini di tempod’esecuzione. Dalle interviste fatte agli sviluppatori di O3-DPACS (5 persone) sono stati ricavati dei

dati soggettivi sui tempi d’esecuzione da cui sono emersi i seguenti dati.

Tipo di test Prima Dopo

Unit Test  2-15 minutiImmediati ed automatici

Functional Test  15-60 minuti

È stato possibile distinguere due categorie di test a seconda del tempo necessario per la loro

esecuzione. Quelli che ho qui riportato come “Unit Test” sono quelli più semplici e veloci, la cui

verifica non richiede più di 15 minuti. Ve ne sono altri che sono più complessi e che possono

richiedere fino a 60 minuti. In entrambi i casi con la nuova infrastruttura la loro esecuzione è

immediata ed automatica.

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

51

Glossario

HL7: standard internazionale che definisce un protocollo di comunicazione tra sistemi informativisanitari

DICOM: standard per la diagnostica di immagini

IHE: iniziativa internazionale che promuove l’interoperabilità tra sistemi informativi sanitari

attraverso l’indicazione di standard e processi comuni per facilitare l’integrazione tra software

ospedalieri eterogenei.

XDS-I: profilo di IHE per la condivisione di “puntatori” dicom (Key Object Selection, KOS) tra sistemi

informativi diversi.

JMX: Java Management Extension, tecnologia Java che consente la pubblicazione di interfacce per lagestione delle applicazioni java. Le interfacce sono chiamate MBean e vengono registrate in un

MBeanServer con un nome univoco. Tramite l’MBeanServer è possibile invocare i metodi esposti

dagli MBean, ai quali si possono anche passare dei parametri, consentendo così la configurazione a

runtime di applicazioni tramite un’interfaccia standard. 

JNDI: è una API java per servizi di directory quali LDAP, RMI, DNS. Nei container Java Enterprise è

utilizzato per registrare risorse messe a disposizione dal container per le applicazioni che vi sono

ospitate. Tra queste risorse ci sono i DataSource per la connessione ai DMBS.

SVN: Subversion, sistema per la gestione del versionamento di codice sorgente.

Bibliografia

[1]  UNI EN ISO 13485:2003

[2]  UNI CEN ISO/TR 16969 (guida per l’applicazione della 13485) 

[3]  CEI EN 60601-1-4 norme generali per la sicurezza (sistemi elettromedicali programmabili)

[4]  CEI EN 62304 Norma (Software per dispositivi medici – processi relativi al ciclo di vita delsoftware)

[5]  Manuale per la classificazione dei dispositivi medici “borderline” http://ec.europa.eu/health/medical-devices/files/wg_minutes_member_lists/borderline_manual_ol_en.pdf  

[6]  M. Fowler, D. Rice, M. Foemmel, E. Hieatt, R. Mee, R. Stafford  

Patterns of Enterprise Application Architecture - Addison-Wesley Professional, 2002

[7]  P. Tahchiev, F. Leme, V. Massol, G. Gregory 

JUnit in Action, Second Edition - Manning Publications, 2010

[8]  Graham Bath, Judy McKay 

The Software Test Engineer's Handbook - Rocky Nook, 2008

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

52

 Appendice

o3 Consortium & o3 Enterprise Projects Management  

Displaying 48 issues at 21/Feb/12 09:32:54 AM.

IssueType

Summary Area

SYS Bug Sometimes the second instance of a study is not stored in fastestAccess database

SYS Bug Change class Dbms to include the chance to use both Oracle and non-Oracledatasources

SYS Bug Oracle out of resources: ORA-01000 maximum open cursors exceeded

SYS Bug Correct getRetrievalInfo under Oracle

SYS Bug On Oracle: querying by study date brings an Exception

SYS Bug [StorageCommitment] Unable to retrieve information, the queries executed on PACSDB are wrong

SYS Bug Problems in inserting records in "Images" table

SYS Bug [CMove] The connection is released before the ack by the SCP dicom

SYS Bug Cancel and Abort seem not to work properly

SYS Bug C-FIND: when asking ProcedureCodeSeq a NullPointerException is thrown

SYS Bug [MoveServer] If at least patient id is specified, the system throws an Exception

SYS Bug Correct getDataForCMove and getRetrievalInfo

SYS Bug C-FIND: Check that Required fields are supported correctly

SYS Bug Presentation Contexts may not be handled properly

SYS Bug Move Dealer does not retrieve results by called by WADO, when this is called usingprivate ip

SYS Bug O3-DPACS ignores c-cancel requests

SYS Bug CalledAET is never checked

SYS Bug [Query] Ranged matching on the studies doesn't work (in modality "from Date")

SYS Bug [ForwarderService] Service locks down after first run service

SYS Bug The timer which checks whether the storage media is running out of space does notconsider the media type

SYS Bug Services don't start from web if autostart is not used

SYS Bug [Dicom Server and HL7 Server] The configuration isn't reloaded correclty

SYS Bug Forwarder Service doesn't work on Oracle

SYS Bug Compressing and storing images with jai not properly installed, fails. A success statusis however returned.

storage

SYS Bug Storage media could not save the image

SYS Bug Worklist search on intervals are not cross-dbms worklist

SYS Bug Worklists: management of timestamps in other DBs

SYS Bug [Worklist] Some Modality SCU refuse the worklist

SYS Bug Not all Worklist tags are treated correctly

SYS Bug [WorkList] if the third party view doesn't contain all aspected comlumns, the worklistserver throw up an exception.

SYS Bug [Worklist] The system put SPSStartDate in the PatientBirthdate Dicom Tag

SYS Bug ADT A40 should not update the target information

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

53

SYS Bug Single quotes in Patient Id do not allow proper storage

SYS Bug Multiframe generation: wrong series UID in generated file

SYS Bug Some exceptions are fake and need to be removed

SYS Bug Memory consumption too high when processing hash

SYS Bug If Procedure Code Sequence is requested, possible nullpointer exception

SYS Bug If more than two MBeanServers are registered on MBeanServerFactory ambiguos logmessage are sended.

SYS Bug [Image Masking] If there is a difference between TS saved in FileMetaInfo andTranferSyntax dicom tag image masking propagates this discrepany and dcm4che libthrow an Exception

SYS Bug The creation of ATNA message has not to be blocking, Better management of presentation context and transfersyntax

SYS Bug FORWARDER: When deleting a study, update the available bytes in PhysicalMedia

SYS Bug installation following the instructions fails

SYS Bug IMAGEIO Bug: Use a jai_imageio.jar released later than Dec 4 2007

SYS Bug exception on duplicated ProtocolCodeSequence...

SYS Bug if there isn't any Node config in the DB the o3-dpacs servers note start.

SYS Bug If the node has the compressione enabled but does not accept compressed images,O3-DPACS should not compress them when sending.

SYS Bug when Patient ID is the same between two patients, O3-DPACS should not accept thestudy

SYS Bug when Anonymization is enabled, query with teh patient first name, last name andbirdth day should be disabled

Generated at Tue Feb 21 09:32:54 CET 2012 by Giacomo Petronio using JIRA 4.2.4-b591#591.

6 - Estrazione dei bug del sistema e suddivisione per aree

Stored Procedure Tipo Categoria Classe di test 

 ADDNEWPATIENT insert patient InsertPatientStoredProceduresTest 

 ADDNEWSTUDY  insert study StudyStoredProceduresTest 

 ADDSTUDYTRACKING insert availability AvailabilitySPTest 

 ARCHIVESTUDY  update media MediaSPTest 

COMPLETEFORWARDPROCESS forward ForwardSPTest COMPLETEMFCREATION mf MultiFrameSPTest 

COMPLETEOLDSTUDIES availability AvailabilitySPTest 

COMPLETESTUDY  availability AvailabilitySPTest 

DELETEINSTANCES delete instance InstancesSPTest 

DOCHANGEPASSWORD conf ConfigurationStoredProceduresTest 

GETALLSERIESFROMSTUDY  select series SeriesStoredProceduresTest 

GETALLSTUDIESFROMPATIENT select study StudyStoredProceduresTest 

GETDATAFORCMOVE move MoveSPTest GETEMAILCONFIGURATIONS select email EmailStoredProceduresTest 

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

54

GETEMAILFROMROLEFK  select email EmailStoredProceduresTest 

GETEVENTEMAIL select email EmailStoredProceduresTest 

GETGLOBALCONFIGURATION select conf ConfigurationStoredProceduresTest 

GETINSTANCES select instance InstancesSPTest 

GETORCREATEPATIENT insert patient InsertPatientStoredProceduresTest 

GETPASSWORDCONSTRAINTS conf ConfigurationStoredProceduresTest 

GETPATIENTBASICINFO select patient SelectPatientStoredProceduresTest 

GETPATIENTBASICINFOAN select patient SelectPatientStoredProceduresTest 

GETPATIENTHL7CONTEXTSTUDIES select patient SelectPatientStoredProceduresTest 

GETPATIENTINFO select patient SelectPatientStoredProceduresTest 

GETPATIENTINFOFORRECO select patient SelectPatientStoredProceduresTest 

GETRETRIEVEALINFO OthersSPTest 

GETSERIESBASICINFO select series SeriesStoredProceduresTest 

GETSERIESINSTANCES select instance InstancesSPTest 

GETSTUDIESFORMOVEVISIT select move MoveSPTest 

GETSTUDIESTOVERIFY  select studyverifier StudyVerifierSPTest 

GETSTUDYBASICINFO select study StudyStoredProceduresTest 

GETSTUDYBASICINFOAN select study StudyStoredProceduresTest 

GETSTUDYINFOFORRECO select study StudyStoredProceduresTest 

GETURLTOINSTANCE media MediaSPTest GETUSERFOREMAIL select email EmailStoredProceduresTest 

GETVERIFIEDSTUDIESINSTANCES select studyverifier StudyVerifierSPTest 

IAINSERTCORRECTSTUDIES availability AvailabilitySPTest 

IAINSERTCORRECTSTUDY  availability AvailabilitySPTest 

IARECONCILEWRONGSTUDY  availability AvailabilitySPTest 

IASWAPPATIENTASSOCIATION availability AvailabilitySPTest 

INITSCHEDULEPROCESS OthersSPTest 

INSERTHL7ALLERGY  insert patient InsertPatientStoredProceduresTest 

INSERTHL7OBSERVATION insert patient InsertPatientStoredProceduresTest 

INSERTKOSRELATIONSHIP insert OthersSPTest 

INSERTSTUDYTOVERIFY  insert studyverifier StudyVerifierSPTest 

INSERTVERIFIEDDATE update studyverifier StudyVerifierSPTest 

ISCONVERTED mf MultiFrameSPTest 

ISUSERAUTHENTICATED conf ConfigurationStoredProceduresTest 

MAPSETTINGFROMMEDIATOSTUDY  OthersSPTest 

MOVESTUDY  move MoveSPTest 

MOVESTUDYTOPATIENT move MoveSPTest 

5/14/2018 Progetto e realizzazione di un infrastruttura di test per un sistema PACS - slid...

http://slidepdf.com/reader/full/progetto-e-realizzazione-di-uninfrastruttura-di-test-per-un

55

MOVEVISIT move MoveSPTest 

REMOVEKOSRELATIONSHIP OthersSPTest 

RESETSTUDIESTORECONCILE study StudySPTest 

RETRIEVEVISITPERSTUDY  select study StudySPTest 

ROLLBACKCONVERSIONDATE mf MultiFrameSPTest 

SELECTFORWARDEDSTUDIES select forward ForwardSPTest 

SELECTSTUDIESTOARCHIVE select forward ForwardSPTest 

SELECTSTUDIESTOFORWARD select forward ForwardSPTest 

SETEXPIRATIONDATE update conf ConfigurationStoredProceduresTest 

UPDATEFORWARDEDSCHEDULE update forward ForwardSPTest 

UPDATEFORWARDSCHEDULE update forward ForwardSPTest 

UPDATEPASSWORD update conf ConfigurationStoredProceduresTest 

UPDATEPATIENTINFORMATION update patient UpdatePatientStoredProceduresTest 

UPDATEPHYSICALMEDIASIZE update media MediaSPTest 

UPDATESCHEDULE update forward ForwardSPTest 

Tabella 7 - Classificazione delle stored procedure