Testarea clientului REST folosind Instrumentul Restito: Ce este clientul REST?
Ce este REST?
REST înseamnă „Transfer de stat reprezentativ”, care este o nouă modalitate de comunicare între oricare două sisteme la un moment dat. Unul dintre sisteme se numește „Client REST”, iar celălalt se numește „Server REST”.
Înainte de a afla despre Cadrul Restito pentru testarea clienților REST, mai întâi să învățăm câteva elemente de bază.
Ce este REST Client?
Clientul REST este o metodă sau un instrument de invocare a unui serviciu API REST care este expus pentru comunicare de către orice sistem sau furnizor de servicii. De exemplu: dacă un API este expus pentru a obține informații de trafic în timp real despre o rută de la Google, software-ul/instrumentul care invocă API-ul de trafic Google se numește client REST.
Ce este REST Server?
Este o metodă sau un API care este expus comunicării de către orice sistem sau furnizor de servicii. De exemplu, Google expune un API pentru a obține informații despre trafic în timp real pe o anumită rută.
Aici, serverul Google trebuie să funcționeze pentru a asculta orice solicitări către API-ul expus de la diferiți clienți.
Exemplu:
Este timpul să stabilim un scenariu complet End-to-End din definițiile de mai sus.
Să luăm în considerare aplicațiile de rezervare a taxiului precum Uber, deoarece o companie are nevoie de informații în timp real despre situația traficului în jurul rutelor pe care se află un anumit vehicul.
Client de odihnă:
Aici clientul este o aplicație mobilă Uber la care s-a conectat șoferul. Această aplicație trimite o solicitare către API-ul REST expus de Google Maps pentru a obține datele în timp real. De exemplu, o solicitare HTTP GET.
Server de odihnă:
În acest exemplu, Google este furnizorul de servicii, iar API-ul Google Maps răspunde cu detaliile solicitate la cererea aplicației Uber.
Atât clientul, cât și serverul sunt la fel de importante în comunicarea REST.
Aici, am implementat exemple pentru testarea automată numai a clientului REST. Pentru testarea serverului REST, consultați https://www.guru99.com/top-6-api-testing-tool.html.
Ce este Restito?
Restito este un cadru dezvoltat de Mkotsur. Este o aplicație ușoară care vă ajută să executați orice fel de solicitare HTTP. Puteți folosi Restito pentru a vă testa API-urile REST și pentru a căuta probleme în aplicația dvs. sau în rețea.
Cum se testează clientul REST folosind Restito?
Să împărțim exercițiul în următorii 4 pași:
- Creați un client HTTP și o metodă pentru a trimite o solicitare HTTP GET către orice punct final al serverului. Pentru moment, luați în considerare punctul final ca fiind
http://localhost:9092/getevents
.
- Porniți un server Restito pentru a asculta și captura cererile trimise la punctul final „getevents” în localhost
http://localhost:9092/getevents
.
- Creați o clasă de testare pentru a testa clientul de mai sus. Invocați metoda „sendGETRequest” a clientului HTTP pentru a iniția o solicitare GET către API „getevents”.
- Validați apelul HTTP GET utilizând cadrul Restito.
Să ne aprofundăm în fiecare dintre pașii de mai sus.
Pas 1) Creați un client HTTP și o metodă pentru a trimite cererea HTTP GET către orice punct final al serverului.
========== COD JAVA Începe ===========
package com.chamlabs.restfulservices.client; import java.util.HashMap; import java.util.Map; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClientBuilder; import org.json.JSONObject; /** * This class creates a HTTP Client and has a method to send HTTP GET request: * sendGETRequest(..) */ public class RestClient { /** * Constructor for the class RestClient */ public RestClient() { System.out.println("Creating RestClient constructor"); } /** * Method to Send GET request to http://localhost:<<port>>/getevents * @param port * @return true if GET request is successfully sent. False, otherwise. */ public static boolean sendGETRequest(int port) { try { HttpClient client = HttpClientBuilder.create().build(); HttpGet getRequest = new HttpGet("http://localhost:" + port + "/getevents"); //HttpResponse response = client.execute(request); client.execute(getRequest); System.out.println("HTTP request is sent successfully." + "Returning True"); return true; } catch (Exception e) { e.printStackTrace(); } System.out.println("Some exception has occurred during the HTTP Client creation." + "Returning false"); return false; } }
========== COD JAVA se termină ===========
Pas 2) Porniți un server Restito pentru a asculta și captura cererile trimise la punctul final „getevents” în localhost http://localhost:9092/getevents
.
========== COD JAVA Începe ===========
package com.chamlabs.restfultesting.util; import static com.xebialabs.restito.builder.stub.StubHttp.whenHttp; import static com.xebialabs.restito.semantics.Action.status; import static com.xebialabs.restito.semantics.Condition.get; import static com.xebialabs.restito.semantics.Condition.post; import java.util.List; import org.glassfish.grizzly.http.util.HttpStatus; import com.xebialabs.restito.semantics.Call; import com.xebialabs.restito.server.StubServer; /** * This utility class contains several utility methods like : * restartRestitoServerForGETRequests(..) * restartRestitoServerForPOSTRequests(..) * waitAndGetCallList(..) * * @author cham6 * @email: paperplanes.chandra@gmail.com * @fork: https://github.com/cham6/restfultesting.git * */ public class TestUtil { /** * Utility method to start restito stub server to accept GET requests * @param server * @param port * @param status */ public static void restartRestitoServerForGETRequests (StubServer server, int port, HttpStatus status) { // Kill the restito server if (server != null) { server.stop(); } // Initialize and configure a newer instance of the stub server server = new StubServer(port).run(); whenHttp(server).match(get("/getevents")).then(status(status)); } /** * Utility method to start restito stub server to accept POST requests * @param server * @param port * @param status */ public static void restartRestitoServerForPOSTRequests (StubServer server, int port, HttpStatus status) { // Kill the restito server if (server != null) { server.stop(); } // Initialize and configure a newer instance of the stub server server = new StubServer(port).run(); whenHttp(server).match(post("/postevents")).then(status(status)); } /** * For a given restito stub server, loop for the given amount of seconds and * break and return the call list from server. * * @param server * @param waitTimeInSeconds * @return * @throws InterruptedException */ public static List<Call> waitAndGetCallList (StubServer server, int waitTimeInSeconds) throws InterruptedException { int timeoutCount = 0; List<Call> callList = server.getCalls(); while (callList.isEmpty()) { Thread.sleep(1000); timeoutCount++; if (timeoutCount >= waitTimeInSeconds) { break; } callList = server.getCalls(); } // Wait for 2 seconds to get all the calls into callList to Eliminate any falkyness. Thread.sleep(2000); return server.getCalls(); } }
========== COD JAVA se termină ===========
Pas 3) Creați o clasă de testare pentru a testa clientul de mai sus. Invocați metoda client HTTP sendGETRequest pentru a iniția o solicitare GET către API „getevents”.
========== COD JAVA Începe ===========import junit.framework.TestCase; import com.chamlabs.restfulservices.client.RestClient; import com.chamlabs.restfultesting.util.TestUtil; import com.xebialabs.restito.semantics.Call; import com.xebialabs.restito.server.StubServer; import static org.glassfish.grizzly.http.util.HttpStatus.ACCEPTED_202; import org.json.JSONObject; import java.util.List; import java.util.Map; /** * This class contains several junit tests to validate the RestClient operations like: * sendRequest(..) * sendRequestWithCustomHeaders(..) * sendPOSTRequestWithJSONBody(..) * */ public class RestClientTester extends TestCase { private static final Integer PORT = 9098; private static final Integer PORT2 = 9099; private static final Integer PORT3 = 9097; public RestClientTester() { System.out.println("Starting the test RestClientTester"); } /** * Junit test to validate the GET request from RestClient * Steps: * 1) Create a stub server using Restito framework and configure it to listen on given port * 2) Invoke the sendGETRequest(..) method of RestClient * 3) Restito captures the matching GET requests sent, if any. * 4) Validate if Restito has captured any GET requests on given endpoint * Expected Behavior: * > Restito should have captured GET request and it should have captured only one GET request. * Finally: * > Stop the stub server started using restito. */ public void testGETRequestFromClient() { StubServer server = null; try { //This will start the stub server on 'PORT' and responds with HTTP 202 'ACCEPTED_202' TestUtil.restartRestitoServerForGETRequests(server, PORT, ACCEPTED_202); RestClient.sendGETRequest(PORT); List<Call> callList = TestUtil.waitAndGetCallList(server, 30); assertTrue("GET request is not received from the RestClient. Test failed.", (callList != null) && (callList.size() == 1)); } catch(Exception e) { e.printStackTrace(); fail("Test Failed due to exception : " + e); } finally { if(server != null) { server.stop(); } } }
========== COD JAVA se termină ===========
Pas 4) Cum se validează cererea GET cu anteturi și cererea POST cu corpul folosind cadrul Restito.
========== COD JAVA Începe ===========
/** * Junit test to validate the GET request with headers from RestClient * Steps: * 1) Create a stub server using Restito framework and configure it to listen on given port * 2) Invoke the sendGETRequestWithCustomHeaders(..) method of RestClient * 3) Restito captures the matching GET requests sent, if any. * 4) Validate if Restito has captured any GET requests on a given endpoint * Expected Behavior: * > Restito should have captured GET request, and it should have captured only one GET request. * > Get the headers of the captured GET request * and make sure the headers match to the ones configured. * Finally: * > Stop the stub server started using restito. */ public void testGETRequestWithHeadersFromClient() { StubServer server = null; try { //This will start the stub server on 'PORT' and responds with HTTP 202 'ACCEPTED_202' TestUtil.restartRestitoServerForGETRequests(server, PORT2, ACCEPTED_202); RestClient.sendGETRequestWithCustomHeaders(PORT2); List<Call> callList = TestUtil.waitAndGetCallList(server, 30); assertTrue("GET request is not received from the RestClient. Test failed.", (callList != null) && (callList.size() == 1)); //Validate the headers of the GET request from REST Client Map<String, List<String>> headersFromRequest = callList.get(0).getHeaders(); assertTrue("GET request contains header Accept and its value ", headersFromRequest.get("Accept").contains("text/html")); assertTrue("GET request contains header Authorization and its value ", headersFromRequest.get("Authorization").contains("Bearer 1234567890qwertyuiop")); assertTrue("GET request contains header Cache-Control and its value ", headersFromRequest.get("Cache-Control").contains("no-cache")); assertTrue("GET request contains header Connection and its value ", headersFromRequest.get("Connection").contains("keep-alive")); assertTrue("GET request contains header Content-Type and its value ", headersFromRequest.get("Content-Type").contains("application/json")); } catch(Exception e) { e.printStackTrace(); fail("Test Failed due to exception : " + e); } finally { if(server != null) { server.stop(); } } }
/** * Junit test to validate the POST request with body and headers from RestClient * Steps: * 1) Create a stub server using Restito framework and configure it to listen on given port * 2) Invoke the sendPOSTRequestWithJSONBody(..) method of RestClient * 3) Restito captures the matching POST requests sent, if any. * 4) Validate if Restito has captured any POST requests on given endpoint * Expected Behavior: * > Restito should have captured POST request and it should have captured only one POST request. * > Get the body of the captured POST request and validate the JSON values * Finally: * > Stop the stub server started using restito. */ public void testPOSTRequestWithJSONBody() { StubServer server = null; try { //This will start the stub server on 'PORT' and responds with HTTP 202 'ACCEPTED_202' TestUtil.restartRestitoServerForPOSTRequests(server, PORT3, ACCEPTED_202); RestClient.sendPOSTRequestWithJSONBody(PORT3); List<Call> callList = TestUtil.waitAndGetCallList(server, 30); assertTrue("POST request is not received from the RestClient. Test failed.", (callList != null) && (callList.size() == 1)); //Validate the headers of the GET request from REST Client String requestBody = callList.get(0).getPostBody(); JSONObject postRequestJSON = new JSONObject(requestBody); assertTrue("The timeUpdated in json is incorrect", postRequestJSON.get("timeUpdated").toString().equalsIgnoreCase("1535703838478")); assertTrue("The access_token in json is incorrect", postRequestJSON.get("access_token").toString(). equalsIgnoreCase("abf8714d-73a3-42ab-9df8-d13fcb92a1d8")); assertTrue("The refresh_token in json is incorrect", postRequestJSON.get("refresh_token").toString(). equalsIgnoreCase("d5a5ab08-c200-421d-ad46-2e89c2f566f5")); assertTrue("The token_type in json is incorrect", postRequestJSON.get("token_type").toString().equalsIgnoreCase("bearer")); assertTrue("The expires_in in json is incorrect", postRequestJSON.get("expires_in").toString().equalsIgnoreCase("1024")); assertTrue("The scope in json is incorrect", postRequestJSON.get("scope").toString().equalsIgnoreCase("")); } catch(Exception e) { e.printStackTrace(); fail("Test Failed due to exception : " + e); } finally { if(server != null) { server.stop(); } } } }
========== COD JAVA se termină ===========
Avantajele utilizării cadrului Restito pentru testarea clientului REST
Iată avantajele/beneficiile Cadrului Restito pentru testarea clienților ReST
- Nu avem nevoie ca serverul REST să fie dezvoltat pentru a testa clientul REST.
- Restito oferă utilități și metode puternice și variate pentru a bate joc de comportamentul diferit al unui server. De exemplu: pentru a testa modul în care clientul REST se comportă atunci când Serverul răspunde cu eroare HTTP 404 sau eroare HTTP 503.
- Serverele Restito pot fi configurate în câteva milisecunde și pot fi terminate după finalizarea testelor.
- Restito acceptă toate tipurile de conținut al metodei HTTP, cum ar fi comprimat, necomprimat, unificat, aplicație/text, aplicație/JSON etc.
Dezavantajele utilizării cadrului Restito pentru testarea clientului REST
Iată dezavantajele/dezavantajele cadrului Restito pentru testarea clienților ReST
- Sursa clientului REST ar trebui să fie ajustată pentru a considera „localhost” ca o mașină server.
- Deschiderea serverului în orice port poate intra în conflict dacă folosim un port folosit în mod obișnuit, cum ar fi „8080” sau „9443” etc.
- Este recomandat să utilizați porturi precum 9092 sau 9099, care nu sunt utilizate în mod obișnuit de alte instrumente.
Rezumat
- REST înseamnă „Representational State Transfer”, care este un nou mod standard de comunicare între oricare două sisteme la un moment dat.
- Clientul REST este o metodă sau un instrument de invocare a unui serviciu API REST care este expus comunicării de către orice sistem sau furnizor de servicii.
- În metoda RestServer sau un API care este expus pentru comunicare de către orice sistem sau furnizor de servicii.
- Restito este o aplicație ușoară care vă ajută să executați orice fel de solicitare HTTP
- Creați un client HTTP și o metodă pentru a trimite o solicitare HTTP GET către orice punct final al serverului
- Porniți un server Restito pentru a asculta și captura cererile trimise către punctul final „getevents”.
- Porniți un server Restito pentru a asculta și captura cererile trimise la punctul final „getevents” în localhost
- Aici, am implementat exemple pentru testarea automată numai a clientului REST.
- Nu avem nevoie ca serverul REST să fie dezvoltat pentru a testa clientul REST.
- Sursa clientului REST ar trebui să fie ajustată pentru a considera „localhost” ca o mașină server.