web services testing using apache http client
Aquest tutorial tracta sobre la realització de diverses operacions CRUD en serveis web i la prova de serveis web mitjançant client HTTP Apache:
En aquest Sèrie completa de tutorials de proves API , hem après que els serveis web actuen com un mitjà de comunicació entre màquines client i servidor que interactua a través d’una xarxa. Ho vam explicar tot Proves API mitjançant POSTMAN al nostre tutorial anterior.
En aquest article, farem èmfasi en com provar els serveis web mitjançant el client HTTP Apache i realitzar diferents operacions CRUD als serveis web. També es parlarà dels diferents tipus de clients REST disponibles per a proves de backend.
per què escolliu la pregunta de l'entrevista de proves de programari
Què aprendreu:
- Què és un servei web?
- Què és el client REST?
- Operacions CRUD mitjançant el client HTTP Apache
- Conclusió
Què és un servei web?
Els serveis web són un mitjà de comunicació entre màquines client i servidor que interactua a través d’una xarxa amb l’ajut de protocols HTTP. Els serveis web solen ser API que no s’instal·len ni s’emmagatzemen localment, però estan disponibles en núvols o en alguns servidors remots.
Consulteu l'exemple següent per entendre com funcionen els serveis web.
MakeMyTrip i Goibibo.com són alguns dels famosos llocs web de reserves de vols i hotels i hi ha diferents proveïdors de vols disponibles com Indigo, Air India i Etihad, etc.
Si un client vol reservar un vol de Nova York a Londres, pot navegar directament al portal del proveïdor de vols o pot reservar a través de proveïdors externs. Si fan reserves a través de proveïdors externs com MakeMyTrip i altres llocs de reserves, en pocs segons compararan i mostraran els resultats proporcionant detalls del vol com el preu més baix, el temps de vol i molta més informació.
La pregunta que sorgeix aquí és, de quina manera, exactament, en qüestió de segons ens proporcionen la informació? Què fan exactament?
Des de la interfície d’usuari, agafen tota la informació necessària i l’emmagatzemen en un fitxer JSON o XML i criden les API del proveïdor amb un testimoni d’autenticació mentre exposen les seves API i, en resposta, el lloc del proveïdor de vols torna la resposta JSON / XML a MakeMyTrip i converteixen la resposta rebuda i mostren els detalls a la IU.
Tipus de serveis web
Hi ha dos tipus de serveis web, a saber
- API SOAP
- API REST
Vegem les diferències entre aquests dos serveis web tal com s’indiquen a la imatge següent.
Fitxers JSON / XML al servei web
Deixem que el sistema S1 es retorni en llenguatge J2EE i el sistema S2 es retorni en .NET o Python i sabem que ambdues tecnologies són completament diferents les unes de les altres per motius de seguretat. Llavors, com compartirà el codi S2 amb un altre sistema?
Per tant, el sistema S2 exposa les seves API al sistema S1 sense exposar la lògica empresarial i el sistema S2 comparteix el nom de l’API, l’URL de l’API, el format de l’API i la clau d’autenticació / clau de testimoni per accedir al seu sistema. La comunicació es produeix entre els dos sistemes mitjançant fitxers JSON o XML.
Per què només el fitxer JSON / XML?
S'utilitzen fitxers JSON / XML perquè es tracta de recopiladors de dades. Qualsevol informació particular s’emmagatzema en formats JSON o XML, ja que són lleugers i són un llenguatge estàndard per comunicar-se entre dues interfícies / plataformes o sistemes diferents.
Per tant, l’API sempre s’utilitza quan dos sistemes independents interactuen entre si, ja sigui localment, dins del sistema o a través de la xarxa.
Què és el client REST?
El client REST és una eina que crida a les API. S’utilitza en proves de backend quan no hi ha cap interfície d’usuari per trucar a les API. Alguns clients REST populars són el client HTTP Apache, POSTMAN, SOAP UI, Swagger i molts més.
Aquí, en aquest article, només parlarem del client HTTP Apache i tractarem altres clients HTTP diferents en els nostres futurs articles.
Configuració del client HTTP a Eclipse
# 1) Obriu Eclipse i creeu un nou projecte Maven.
# 2) Suprimiu els paquets ficticis proporcionats per MAVEN i.e. 'Src / main / java' i 'Src / test / java'
# 3) Aneu al fitxer pom.xml i elimineu la dependència de JUnit ja que no la necessitem.
# 4) A continuació, necessitem la biblioteca del client HTTP, la biblioteca del nucli HTTP, la biblioteca de l’analitzador JSON, la biblioteca TestNG i la biblioteca de vinculació de dades de Jackson.
# 5) Afegiu les dependències anteriors (biblioteca) al fitxer pom.xml.
Biblioteca del client HTTP:
Biblioteca HTTP Core:
Biblioteca d'analitzadors JSON:
Biblioteca TestNG:
# 6) Descarregueu les versions més recents i estables. No afegirem pot de seleni al nostre projecte, ja que estem fent proves completes de backend. El fitxer final pom.xml té l’aspecte que es mostra a la imatge següent:
# 7) A continuació, creeu un marc per a la prova de l'API
a) Creeu un paquet 'com.qa.config' -> Creeu un fitxer 'config.properties' i emmagatzemeu tots els URL.
b) Creeu un altre paquet 'qa.com.base' -> Creeu una classe 'testBase.java' que serà una classe pare per a totes les classes. Conté funcions comunes per a tots els mètodes.
c) Creeu un altre paquet 'com.qa.client' i la classe 'restClient.java'. Conté codi per obtenir trucades GET, POST, DELETE, PUT.
d) Creeu un altre paquet 'com.qa.data' i la classe 'user.java' que defineixi les diferents propietats de l'usuari.
és) Finalment, creeu un paquet 'com.qa.Test' a 'src / test / java' i declareu un mètode i funcions principals per provar tots els mètodes GET, PUT, POST i Delete.
f) L'estructura final del marc serà com es mostra a continuació:
g) Utilitzeu l'API fictícia proporcionada per aquest lloc REQ RES .
Mètodes HTTP o operacions CRUD
Vegem diferents mètodes HTTP o operacions CRUD que automatitzem.
A continuació, es denomina operacions CRUD:
- C : Crea (significa trucada POST)
- R : Recupera (significa trucada GET)
- U : Actualització (significa trucada PUT)
- D : Suprimeix (significa suprimir trucada)
Paràmetres als serveis web REST
Valideu o ressalteu els paràmetres següents als serveis web de REST:
(i) URI: L'URI és la combinació del paràmetre URL + Path i el paràmetre de consulta.
Exemple: http://api.com/service/account/1
Aquí, api.com és l'URL del servidor S2, servei és el titular. En aquest servei, el titular acudeix al compte class, i a partir d'aquesta classe de compte, anomena el mètode compte = 1. En totes i cadascuna de les trucades passem l’URI.
(ii) Càrrega útil: Dades JSON / XML que alimentem al sistema.
(iii) Codi d'estat: Per a cada resposta, obtenim els codis d'estat.
A continuació, es detallen uns quants codis:
- 200: D’acord, tot funciona bé.
- 201: S’ha creat correctament quan feu una trucada POST o creeu una entitat nova.
- 400: La càrrega útil és incorrecta, l'URL final és incorrecte i mostra una petició incorrecta.
- 404: Actualitzeu o suprimiu una entitat i aquesta entitat no està disponible. Aleshores obtindrem el resultat perquè no s'ha trobat la sol·licitud.
- 500: Suposem que el servidor S2 està inactiu, obtenim un error intern del servidor.
- 401: Error d'autenticació
Feu clic a aquí per obtenir tots els codis d'estat.
(iv) Capçaleres: Com el testimoni d’autenticació, l’identificador / contrasenya d’usuari, el tipus de contingut, etc.
com escriure històries d’usuaris i criteris d’acceptació
Operacions CRUD mitjançant el client HTTP Apache
# 1) Obteniu una trucada
Com es comporta l'operació GET Call?
Get Call envia la sol·licitud i rep la resposta. Aquí no passem cap JSON ni la càrrega útil, passem un URI, en què URL (paràmetre del camí final, paràmetre de consulta) juntament amb la capçalera, si està disponible.
quants proveïdors de correu electrònic hi ha
Abans d’escriure el codi de trucada GET, tingueu en compte les coses següents:
- Necessiteu un mètode GET
- A continuació, necessiteu un URL
- Un cop premeu el botó d'enviament, obtindreu la resposta. A continuació, emmagatzemeu la resposta.
- Necessiteu codi d'estat, capçaleres.
Consulteu la captura de pantalla següent del client POSTMAN que mostra la resposta de trucada GET:
A la classe restClient.java,
(i) Creeu el mètode GET que cridarà l'URL i obtindrà la resposta en forma d'objecte JSON sense capçalera.
package com.qa.Client; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Map; import org.apache.http.Header; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import org.json.JSONException; import org.json.JSONObject; public class restClient { // create GET Method, which will call the URL and get the response in the form of JSON object without Header public CloseableHttpResponse getMethod(String Url) throws ClientProtocolException, IOException, JSONException{ /*Call HTTPClients class from HTTPClient library added in POM.xml. Call createDefault() method present in HTTPClients class, which will create a client connection. And this createDefault() method returns 'CloseableHttpClient' object which is an abstract class. And we are creating a reference to that abstract class */ CloseableHttpClient httpClient=HttpClients.createDefault(); /*create an object for HttpGet class, which is used for HTTP GET Request. And pass the URL which is to be loaded*/ HttpGet htttpGet = new HttpGet(Url); /*execute the HTTP GET Request, means it will hit the GET API call as we click SEND button from POSTMAN client. httpClient.execute() method returns the response 'CloseableHttpResponse' interface and store it in reference variable So the complete response is stored in CloseableHttpResponse And fetch all the details, in our test case/test method */ CloseableHttpResponse closeableHttpResponse = httpClient.execute(htttpGet); return closeableHttpResponse; } }
(ii) Creeu la classe principal 'getAPITest.java' a 'src / test / java'
Sortida
# 2) Truca POST
POST Call crea un compte o crea una entitat nova.
Exemple - Passeu aquests detalls com el nom, el treball i la capçalera a la càrrega útil JSON. El servidor S2 estarà enllaçat amb algunes bases de dades, per exemple, Oracle i té un nom de taula anomenat Taula de comptes. El mètode POST crearà una entrada a la base de dades i el servidor S2 transmet la informació al client S1. Recordeu que l'operació de trucada POST sempre s'utilitza per crear una nova entitat.
En el mètode POST, hem de passar l'URL i la càrrega útil.
Descarregueu aquesta dependència ja que necessitem convertir la classe Java a objecte Java que a objecte JSON.
A la classe restClient.java,
(i) Creeu un mètode POST, que cridarà l'URL i publicarà la resposta.
public class restClient { public CloseableHttpResponse POST(String url,String entityString,HashMap headermap) throwsClientProtocolException, IOException{ /*Call HTTPClients class from HTTPClient library added in POM.xml and createDefault() method present in HTTPClients class, which will create a client connection and this createDefault() method returns 'CloseableHttpClient' object which is an abstract class and we are creating reference to that abstract class */ CloseableHttpClient httpClient=HttpClients.createDefault(); /*create an object for HttpPost class, which is used for HTTP POST Request and pass the URL which is to be loaded */ HttpPost htttpPost = new HttpPost(url); /*define pay load, use setEnity method present in HTTPPOST class and pass the payload entity */ htttpPost.setEntity(new StringEntity(entityString)); //Create a for loop and iterate the hashmap, and store the header for(Map.Entry entry : headermap.entrySet()){ htttpPost.addHeader(entry.getKey(),entry.getValue()); } //Execute the POST request CloseableHttpResponse closeableHttpResponse = httpClient.execute(htttpPost); return closeableHttpResponse; } }
(ii) Creeu la classe principal 'postAPI_Test.java' a 'src / test / java'.
//Inherit testBase class public class postAPI_Test extends testBase { //Create global methods testBase testbase; String serviceURL; String apiURL; String URL; restClient restClient; HttpResponse closeableHttpResponse; // In before method call the properties file @BeforeMethod public void setUp() throws ClientProtocolException, IOException, JSONException{ //call the constructor of base class and execute the properties file testbase = new testBase(); serviceURL = prop.getProperty('URL'); apiURL = prop.getProperty('serviceURL'); URL = serviceURL+apiURL; } //Main method which calls the GET method @Test public void POSTAPITest() throws ClientProtocolException, IOException, JSONException{ restClient = new restClient(); //Pass the Request Header HashMap headrMap = new HashMap(); headrMap.put('Content-Type', 'application/json'); /*Use Jackson API for doing marshaling, means converting java to java object to JSON Object and vice versa Use ObjectMapper class */ ObjectMapper mapper = new ObjectMapper(); //Create object of Users class, expected users users user = new users('John','Manager'); //Convert java object 'user' to JSON Object using writeValue(), pass the path where to store the JSON file and the object to be converted */ mapper.writeValue(new File('.\data\users.json'), user ); //convert java object to json in string String userJsonString = mapper.writeValueAsString(user); System.out.println(userJsonString); //Call the POST Method closeableHttpResponse = restClient.POST(URL, userJsonString, headrMap); //Fetches status, header, and JSON response from CloseableHttpResponse //1.Fetch Status Code int statusCode = closeableHttpResponse.getStatusLine().getStatusCode();//Get the Status code System.out.println('Status Code --->' +statusCode); //Validate the status code using Assert class Assert.assertEquals(statusCode, response_Status_Code_201,'Status is not 200'); /*2.Fetch the JSON String use EntityUtils class and call to String method, where we have to pass entity and format entity is available in closeableHttpResponse and pass UTF-8 format because we want pure string so complete JSON will be stored in a String, so we need to convert an entire string into a JSON object */ String responseString = EntityUtils.toString(closeableHttpResponse.getEntity(), 'UTF-8'); /*as we added one JSON library, from that library call JSON class and pass the response string. So this JSON object converts the string into JSON */ JSONObject responseJson = new JSONObject(responseString); System.out.println('Response JSONfrom API --->'+responseJson); /*Convert JSON to java actual User Object we are getting */ users userResObj = mapper.readValue(responseString, users.class); Assert.assertTrue(user.getName().equals(userResObj.getName())); Assert.assertTrue(user.getJob().equals(userResObj.getJob()));} }
Sortida:
# 3) Truca PUT
Mitjançant l'operació de trucada PUT, podeu crear una entitat nova i actualitzar una entitat existent.
A la classe restClient.java,
(i) Creeu un mètode PUT, que cridarà l'URL i actualitzarà la resposta.
public class restClient { public CloseableHttpResponse PUT(String url,String entityString,HashMap headermap) throwsClientProtocolException, IOException{ /*Call HTTPClients class from HTTPClient library added in POM.xml. Call createDefault() method present in HTTPClients class, which will create a client connection and this createDefault() method returns 'CloseableHttpClient' object which is an abstract class and we are creating reference to that abstract class*/ CloseableHttpClient httpClient=HttpClients.createDefault(); /*create an object for HttpPut class, which is used for HTTP PUT Request and pass the URL which is to be loaded */ HttpPut htttpPut = new HttpPut(url); /*define pay load, use setEnity method present in HTTPPUT class and pass the payload entity */ htttpPut.setEntity(new StringEntity(entityString)); /*create a for loop, iterate and store the header */ for(Map.Entry entry : headermap.entrySet()){ htttpPut.addHeader(entry.getKey(),entry.getValue()); } //Execute the PUT request CloseableHttpResponse closeableHttpResponse = httpClient.execute(htttpPut); return closeableHttpResponse; } }
(ii) Creeu la classe principal 'putAPI_Test.java' a 'src / test / java'
//Inherit testBase class public class putAPI_Test extends testBase { //Create global methods testBase testbase; String serviceURL; String apiURL; String URL; restClient restClient; HttpResponse closeableHttpResponse; // in before method call the properties file @BeforeMethod public void setUp() throws ClientProtocolException, IOException, JSONException{ //Call the constructor of the base class and execute the properties file testbase = new testBase(); serviceURL = prop.getProperty('URL'); apiURL = prop.getProperty('serviceURL'); URL = serviceURL+apiURL; } //Main method which calls PUT method @Test public void PUTAPITest() throws ClientProtocolException, IOException, JSONException{ restClient = new restClient(); //Pass the Request Header HashMap headrMap = new HashMap(); headrMap.put('Content-Type', 'application/json'); /*use Jackson API, for doing marshaling means converting java to java object to JSON Object and vice versa, use ObjectMapper class */ ObjectMapper mapper = new ObjectMapper(); //Create object of Users class, new users users user = new users('JohnMarry Dicosta','HRManager'); /*Convert java object 'user' to JASON Object using writeValue() and pass the path where to store the JSON file and the object to be converted */ mapper.writeValue(new File('.\data\users.json'), user ); //convert java object - > JSON - >String String userJsonString = mapper.writeValueAsString(user); System.out.println(userJsonString); //Call the PUT Method closeableHttpResponse = restClient.PUT(URL, userJsonString, headrMap); /*fetch status, header, JSON response from CloseableHttpResponse Fetch Status Code */ int statusCode = closeableHttpResponse.getStatusLine().getStatusCode(); System.out.println('Status Code --->' +statusCode); //Validate the status code using Assert class Assert.assertEquals(statusCode, response_Status_Code_200,'Status is 200'); /*2.Fetch the JSON String, use EntityUtils class and call to String method where we have to pass entity and format entity is available in closeableHttpResponse and pass UTF-8 format because we want a pure string. So complete JSON will be stored in a String, so we need to convert an entire string into a JSON object */ String responseString = EntityUtils.toString(closeableHttpResponse.getEntity(), 'UTF-8'); /* From JSON library, call JSON class and pass the response string. This JSON object converts the string to JSON */ JSONObject responseJson = new JSONObject(responseString); System.out.println('Response JSONfrom API --->'+responseJson);}
Sortida
# 4) Suprimeix la trucada
L’operació de supressió de trucades és senzilla, és a dir, suprimiu l’identificador de compte i passeu la informació en un fitxer JSON.
A la classe restClient.java,
(i) Crea un mètode de supressió, que cridarà URL i suprimirà el registre.
public CloseableHttpResponse Delete(String url) throws ClientProtocolException, IOException{ /*Call HTTPClients class from HTTPClient library added in POM.xml and createDefault() method present in HTTPClients class, which will create a client connection and this createDefault() method returns 'CloseableHttpClient' object which is an abstract class and we are creating reference to that abstract class */ CloseableHttpClient httpClient=HttpClients.createDefault(); /*create an object for HttpDelete class, which is used for HTTP Delete Request, and pass the URL to be loaded*/ HttpDelete htttpDelete = new HttpDelete(url); //execute Delete request CloseableHttpResponse closeableHttpResponse =httpClient.execute(htttpDelete); return closeableHttpResponse; }
(ii) Creeu la classe principal 'deleteAPI_Test.java' a 'src / test / java'.
public class deleteAPI_Test extends testBase { //Create global methods testBase testbase; String serviceURL; String deleteuserUrl; String URL; restClient restClient; HttpResponse closeableHttpResponse; // In before method call the properties file @BeforeMethod public void setUp() throws ClientProtocolException, IOException, JSONException{ //call the constructor of the base class and execute the properties file testbase = new testBase(); serviceURL = prop.getProperty('URL'); deleteuserUrl = prop.getProperty('deleteuser'); URL = serviceURL+deleteuserUrl; } //The Main method which calls the Delete method @Test public void deleteAPI() throws ClientProtocolException, IOException, JSONException{ restClient = new restClient(); //Method returns closeableHttpResponse type closeableHttpResponse = restClient.Delete(URL); /*fetch status code, header, JSON response from CloseableHttpResponse -Fetch Status Code */ int statusCode = closeableHttpResponse.getStatusLine().getStatusCode(); System.out.println('Status Code --->' +statusCode); //Validate the status code using Assert class Assert.assertEquals(statusCode, response_Status_Code_204,'Status is 204 No Content'); }
Sortida
Abans de validar qualsevol resposta, obteniu l'URL correcta del desenvolupador, comproveu si obteniu la resposta esperada del servidor, prepareu casos de prova per a cada escenari i organitzeu casos de prova en funció de la funcionalitat w.r.t.
Conclusió
En aquest article, hem explicat com utilitzar el client HTTP Apache per automatitzar les trucades POST, PUT, GET i Delete amb exemples de codi. També hem debatut sobre els tipus de serveis web i la importància dels fitxers JSON / XML i per què s’utilitzen.
PREV Tutorial | PRIMER Tutorial
Lectura recomanada
- Tutorial de serveis web: components, arquitectura, tipus i exemples
- 15+ Tutorials SoapUI: la millor eina de prova de l'API de serveis web
- Preguntes i respostes d’entrevistes dels serveis web d’Amazon (AWS)
- Top 20 de preguntes i respostes d’entrevistes de serveis web RESTful
- Top 25 de preguntes i respostes d’entrevistes de serveis web de Java
- Top 45 de preguntes i respostes d'entrevistes de serveis web (RESTful, SOAP, preguntes de seguretat)
- Proves de rendiment dels serveis web mitjançant LoadRunner VuGen Scripting
- Tutorial de proves API: una guia completa per a principiants