Usare Groovy con SOAPUI per l’automazione dei test R. Turco Nell’articolo “Realizzare un Framework di Test con SOAPUI” abbiamo mostrato le potenzialità di SOAPUI. In
realtà esso permette di lavorare non solo per Web Services SOAP (su http/https o su jms) ma anche quelli REST, la cui descrizione è attraverso le WADL. SOAPUI ci permette vari scenari: a) Simulare un servizio (Mock (Mock Service) disponendo disponendo della sola WSDL del servizio esterno esterno al nostro sistema e quindi ottenere risposte da esso a richieste del nostro sistema b) Testare un nostro Web Service Groovy ci permetterà, invece, di rendere dinamici i valori marcati con ? da passare nelle request o nelle response. Esamineremo Esamineremo il caso b), b), in questo breve tutorial. Se possibile usiamo usiamo l’ultima versione disponibile di SOAPUI. Il Proxy In tale caso sul vostro PC preparate la suite di Test e in remoto c’è il Web Service. In tal caso vi serve
eventualmente, in una azienda, settare il proxy (per andare in remoto) settando da File -> Preferences -> Proxy Settings -> Manual (inserire tutte le info). Se, invece, il Web Service ce l’avete in locale al PC per testarlo Proxy Settings -> None. Il Progetto
Create un nuovo progetto con New SOAP Project -> Automation-PrepaidMobileNumberInformation. In Initial WSDL si deve mettere la url del servizio implementato che dobbiamo testare. testare. Ad esempio dovreste mettere la URI del servizio in: Initial WSDL-> http://
: http://:8105/IB/se 8105/IB/services/Prepaid rvices/PrepaidMobileNumberIn MobileNumberInformation formationQuery-v1?wsdl Query-v1?wsdl""
(Se invece usate un Mock Service =localhost e la porta deve essere libera altrimenti la cambiate nella WSDL e su SOAPUI come vedremo. La URI la l a trovate nella WSDL del vostro servizio nella parte binding). Tuttavia è possibile che del tutorial vi interessi solo come sfruttare Groovy con SOAPUI e non di sviluppare il servizio, allora vi consiglio di utilizzare il WSDL in APPENDICE e di testarlo prima con un tool per verificarne la validità e che sia well-formed. Attenzione che nel binding, per creare un Mock Service che funzioni da PC, vi conviene mettere nel WSDL il binding a localhost. Per cui adesso ci generiamo il Mock Service dalla WSDL e non implementiamo il servizio. Selezioniamo la WSDL e facciamo check su “Create Request” e “Create Test Suite” e premere OK.
Ora sulla finestra Generate Test Suite selezionare “Single TestCase with one Request for each Operation”. Lasciamo il nome nome della Test Suite che ci propone. propone. Inoltre non volendo sviluppare sviluppare il servizio dobbiamo dobbiamo almeno avere il MockService. Generiamo il Mock Service come segue. Mettendo il mouse su PrepaidMobileNumberInformationQueryBinding con tasto destro del mouse facciamo Generate SOAP Mock Service poi in path (importante)mettiamo /IB/services/PrepaidMobileNumberInformationQuery-v1
Mentre su port mettiamo 8086; questi valori li avremo selezionato dalla WSDL da soap:address location. Lasciamo anche il nome proposto da SOAPUI per il Mock Service. Dovremmo avere adesso una situazione come in figura successiva.
Ora, come detto in premessa, è come se avessimo a disposizione il Servizio implementato che vogliamo testare (il Mock Service). Sono almeno due gli scenari che possiamo fare. Servizio sviluppato da testare – Invio ad esso di varie Richieste ed il Servizio ci dà risposte L’obiettivo in questo caso è testare un servizio realizzato e deployato, per cui è di interesse magari fare vari
tipi di request e aspettarci le risposte del nostro servizio posto sotto sotto test. In generale, come nel caso della nostra WSDL in APPENDICE, potremmo avere sia l’HEADER che il BODY che potremmo voler valorizzare dinamicamente. In tal caso possiamo mettere su vari file la parte tra L’idea è di avere questi pezzi di requests scritte scritte in diversi file con nome nome del tipo TestX.xml dove X è un numerico (1,2,…). In ognuno di esso c’è siolo la parte di body della request.
Sistema sviluppato che fa richieste ad un Web Service – Varie Risposte dal Mock Service
Questo è il caso dove abbiamo il sistema sviluppato che fa richieste ad un Web Service esterno non sviluppato da noi, di cui disponiamo solo la WSDL e lo simuleremo con un Mock Service e siamo interessati a ricevere dal Mock Service varie risposte con valori diversi ovvero response diverse. Possiamo anche in questo caso usare dei file per le response. Directory dei file request e response
Creiamo una directory GroovyTest con le due sottodirectory Requests e Responces. Qui metteremo I file xml, con le sole parti del Body e le valorizzeremo con i valori che ci servono nel test al posto dei ?. Per esempio mettete due file e con valori di body diversi. Mock Service e primo scenario
Attiviamo il Mock Service per fare il primo scenario. Su PrepaidMobileNumberInformationQueryBinding Mock Service -> doppio click e poi sulla freccia verde startare il Mock Service
Test Suite
Posizioniamoci su Test Steps(1) e con tasto destro fare Add Step -> Groovy Script. Denominarlo Groovy Script Step 1. Prepariamoci una request sfruttando la Request1 generata da SOAPUI (copiandola solo, in realtà non serve ma serviranno quelle delle operation) e selezioniamo solo il Body (le parti in rosso): ? ? ? ? ? ?
?
A questo punto dipende dai test che dobbiamo fare. Ci sono test dove magari i campi opzionali non interessano valorizzati e occorre valorizzare solo gli obbligatori. Altri in cui conviene valorizzare ogni cosa. Supponiamo di dover iniziare a fare i test solo dei campi obbligatori. Al posto del ? per le parti obbligatorie, number in questo caso, mettiamo ad esempio 1001 e salviamo questo file nella directory requests col nome Test1.xml, poi ne facciamo un altro col valore 2002 e lo salviamo col nome Test2.xml e così via. Ora passiamo al Groovy Script. Incolliamo questo codice nella finestra che si apre cliccando su Groovy Script: def fileList = [] new File("C: File("C: \\GroovyTest\\requests").eachFile {f -> if (f.isFile()&& f.name.endsWith('.xml')) { def fileName = f.name[0..-1] fileList.add(fileName) log.info fileName } } if (fileList.size() <1) { // testRunner.fail("No request files found") } // context.put('fileList',fileList)
Ovviamente occorre mettere mettere il path giusto dove è la vostra directory. In prima battuta facciamo funzionare funzionare solo il log per vedere se punta alla directory giusta e trova effettivamente due file di richieste. Cliccate sulla freccia verde del Groovy Script e dovrebbe darvi due log relativi ai file che ha trovato. Se è così commentiamo ora l’istruzione di log e scommentiamo le altre due: def fileList = [] new File("C:\\Users\\XXX\\Desktop\\ File("C:\\Users\\XXX\\Desktop\\Groovy\\GroovyTest\\req Groovy\\GroovyTest\\requests").eachFile uests").eachFile {f -> if (f.isFile()&& f.name.endsWith('.xml')) { def fileName = f.name[0..-1] fileList.add(fileName) // log.info fileName } } if (fileList.size() <1) { testRunner.fail("No request files found") } context.put('fileList',fileList)
Ora i valori prelevati vanno inseriti nella request. Ma come? Nella Test Suite creiamo getCreditInfo e getCreditInfo2 e spostiamoli entrambi sotto al Groovy Script (con Move Step Down – tasto destro del mouse). Questo perché devo prima prelevare i valori dai file e poi metterli nella Request). Clicchiamo ora su getCreditInfo e su getCredititInfo2 ed eliminiamo la parte interna a sostituendola con:
${=new File("C:\\GroovyTest\\requests\\" + (context.get('fileList')).last( (context.get('fileList')).last()).text} )).text}
Nel getResponse e getResponse 2 possiamo mettere delle Assert per vedere se ci sono errori o cercare dei valori particolari. Sotto getResponse ad esempio facciamo Assertions e + e scegliamo ad esempio Compliance, Status e Standards e settiamo No SOAP Fault (vogliamo vedere che non ci sono errori). Qua si possono mettere anche altre Assertion in cascata. Nel Mock Service mettiamo due response Response 1 e Response 2 con il return code a 1 e 2, ad esempio. giusto affinché il servizio risponda un valore. Ovviamente dipenderà dai vostri test con che valore il Web Service reale deve rispondere.
Lancio della Test Suite delle Request
Sulla Test Suite con doppio click si apre la finestra a destra. Con click su freccia verde si ottiene il lancio di tutte le request (due nel nostro caso) e la barra che si colora di verde mi indica che i test sono andati OK. Se ci fosse stato un rosso avremmo potuto esaminare quale richiesta fosse andata in errore. Intanto vedendo Step 3 e Step 2 si possono vedere due cose:
Le request partite la prima con 1001 e la seconda con 2002
Le response col return code a 1 e a 2 come risposta ad ad ogni request.
Una suite di Test è fortemente incoraggiata se il numero di test è elevato si guadagna molto tempo in regressione per una anomalia etc. Il compilare dei file con editor xml è estremamente facile e rapido, predisporre SOAPUI anche di più. Altre possibilità sono letture dal DB di valori di interesse, introdotte come Step ordinati, etc. Secondo scenario
Questa volta il Mock Service può aiutarmi a simulare varie risposte quando è il nostro servizio che chiama il Mock Service. Possiamo fare la stessa cosa di prima ma rendendo dinamiche le response questa volta mettendo i file nella sottodirectory responces. Lo lasciamo come esercizio al lettore. Asserts Come nell’altro articolo vi consiglio di usare le assert per verificare varie cose. Infine vi consiglio un
approfondimento approfondimento del linguaggio Groovy. Load Test
SOAPUI è anche forte per organizzare un Load Test ovvero un test di carico. Vedi documentazione http://www.soapui.org/Gettinghttp://www.soa pui.org/Getting-Started/load-t Started/load-testing.html esting.html http://www.soapui.org/loa http://www.soa pui.org/load-testing/creatingd-testing/creating-and-running-loa and-running-loadtests.html dtests.html Database
Per il database, invece, consultare la documentazione al link: http://www.soapui.org/jdbc/t http://www.soa pui.org/jdbc/testing-jdbc-databa esting-jdbc-databases.html ses.html Groovy, SOAPUI e database. E’ possibile interagire col database da SOAPUI anche usando Groovy con l’intenzione di automatizzare gli
step. Si deve conoscere il tipo di database a cui connettersi e la sintassi dei comandi richiesta. Nell’esempio successivo ipotizzo il DB Oracle e una select qualunque. Nel Groovy Script ci devono essere linee di codice del tipo: import groovy.sql.Sql; def con = Sql.newInstance("jdbc:oracle:thin:@::", "", "", "oracle.jdbc.driver.OracleDriver"); def res = con.rows("SELECT sysdate FROM dual") log.info(res[0].sysdate.toString())
con.close()
L’esempio di sopra preleva la data di sistema dalla tabella DUAL e lo stampa a log. In res c’era il risultato
della query. Altre istruzioni sql utili con SOAPUI firstRow( sqlQuery ) : Questo metodo ritorna la prima riga della tabella della query passata in input.
Esempio def res = sql.firstRow(“SELECT * FROM TEST_TABLE WHERE USERID=’12345′”)
Il risultato si può accedere con res[0] o res. res. eachRow( sqlQuery, {closure} ) : Questo metodo è usato per mantenere o modificare l’intero whole
ResultSet basandoci basandoci su qualche condizione. Il secondo argomento argomento è un set di istruzioni che possono essere essere eseguite per ogni risultato. Esempio: sql.eachRow( “SELECT * FROM TEST_TABLE WHERE USERID=’12345′”,
{ println( it.COLUMN_1 ); println( it[2] ); } )
Le println di sopra sono, difatti, eseguite per ogni riga del ResultSet. Le Closure possono avere un qualsiasi numero di statement. Sopra sono 2. execute( sqlQuery ) : E’ usato per operazioni CRUD come INSERT/UPDATE/DELETE e non ritorna ResultSet.
Esempio sql.execute( “DELETE FROM TEST_TABLE WHERE USERID=’12345′ & USERNAME=’SOMENAME’ USERNAME=’SOMENAME’ ” ) sql.execute( “DELETE FROM TEST_TABLE WHERE USERID = ? & USERNAME = ? “, [ “12345”, “SOMENAME” ] )
Il secondo metodo è simile alla tecnica di sql dinamico.
SOAPUI e altre sorgenti dati
SOAPUI può anche leggere dati da un file CSV o da un excel. Vedi http://www.so http://www.soapui.org/da apui.org/data-driven-tests/fun ta-driven-tests/functional-tests.ht ctional-tests.html ml Integrazione con OAUTH2
Vedi http://www.so http://www.soapui.org/oa apui.org/oauth2/oauth uth2/oauth2-overview.html 2-overview.html Monitoraggio
Vedi http://www.so http://www.soapui.org/ap apui.org/api-monitoring.htm i-monitoring.htmll. Ma in questo caso occorre la versione PRO.
Conclusioni
SOAPUI è adatto a Test funzionali e di carico, si integra facilmente con Web Service di tipo SOAP e REST (compreso JMS), JMS), sia http/https, si integra con ogni tipo di database in termini jdbc, con altre fonti dati come excel e csv. Permette l’automazione degli step con Groovy, l’integrazione con un server di autenticazione
come OAUTH2 e il Monitoraggio. Un vero Supereroe!! Alla prossima.
APPENDICE WSDL_PrepaidMobileNumberInformationQuery_Concrete-v1 "> > > > "/> > "/> > "/> > > "/> > "/> "/> > "/> "/> > >
v1"/> v1"/> --> > > > SOAPHeader_v1.1.xsd
"> Definition --> "> > Informazioni di contesto dell'invocazione del servizio > > Sistema da cui proviene la richiesta > Data e Ora di invocazione del servizio servizio > Identifica univocamente il processo dibusiness dibusiness > Identifica il messaggio in maniera univoca > Identifica la transazione per gestire i ritornisincroni > > "> "> "/> > > "> "> "/> > > "> "> > >
"> > > "> > > "> > > > "> Per compatibilità con i diversi prodotti o librerie software (es.Axis2 e BW) si è scelto di utilizzare il tipo string. La restizione applicata accetta il formato: CCYY-MM-DD. Non sono presenti restrizionisul range dei valori. > "> Per compatibilità con i diversi prodotti o librerie software (es.Axis2 e BW) si è scelto di utilizzare il tipo string. La restizione applicata accetta il formato: hh:mm:ss.sss. Non sono presenti restrizioni sul range dei valori. Per gli ulteriori dettagli sul formato fare riferimento alla definizione di Time Data Type W3C, presente al al link:http://www.w3schoo link:http://www.w3schools.com/Sche ls.com/Schema/schem ma/schema_dtypes_da a_dtypes_date.asp te.asp > > Definition --> >
PrepaidMobileNumberInformationQuery.xsd
T.IT.SC.SOA --> "> --> > > > "> > >
END--> START--> "> > > END--> START--> "> > > "> "/> > END--> >
PrepaidMobileNumberInf PrepaidMobileNumberInformationQuery ormationQueryEntities.xsd Entities.xsd
T.IT.SC.SOA --> "> START--> START --> > > END --> START--> > > > > END--> START--> "> > "/> > ">
> > END--> START--> "> > > END--> END--> START--> "> > < bvi:primitiv bvi:primitiveType eType> > < bvi:classN bvi:className ame> >TelephoneNumber TelephoneNumber bvi:className bvi:className> > bvi:primitiveType bvi:primitiveType> > > > "> "/> > > "> > < bvi:primitiv bvi:primitiveType eType> > < bvi:classN bvi:className ame> >Decimal Decimal bvi:className bvi:className> > bvi:primitiveType bvi:primitiveType> > > > "/> > "> > < bvi:primitiv bvi:primitiveType eType> > < bvi:classN bvi:className ame> >DateTime DateTime bvi:className bvi:className> bvi:primitiveType bvi:primitiveType> > > > "/> > END --> START--> "> "/> > > "/> > "/> > "> "> > > END--> >