Test del client REST utilizzando lo strumento Restito: cos'è il client REST?
Cos'è il RIPOSO?
REST sta per “REpresentational State Transfer”, che è un nuovo modo di comunicazione tra due sistemi qualsiasi in un dato momento. Uno dei sistemi si chiama "Client REST" e l'altro si chiama "Server REST".
Prima di conoscere Restito Framework per i test dei client REST, impariamo alcune nozioni di base.
Cos'è il client REST?
REST Client è un metodo o uno strumento per richiamare un'API di servizio REST esposta per la comunicazione da qualsiasi sistema o fornitore di servizi. Ad esempio: se un'API è esposta per ottenere informazioni sul traffico in tempo reale su un percorso da Google, il software/strumento che invoca il Google L'API per il traffico è chiamata client REST.
Cos'è il server REST?
Si tratta di un metodo o di un'API esposta alla comunicazione da parte di qualsiasi sistema o fornitore di servizi. Ad esempio, Google Espone un'API per ottenere informazioni sul traffico in tempo reale su un determinato percorso.
Qui, il Google Il server deve essere attivo e funzionante per poter ricevere richieste all'API esposta da diversi client.
Esempio:
È giunto il momento di stabilire uno scenario end-to-end completo partendo dalle definizioni di cui sopra.
Consideriamo un'applicazione di prenotazione taxi come Uber poiché un'azienda ha bisogno di informazioni in tempo reale sulla situazione del traffico attorno ai percorsi in cui si trova un determinato veicolo.
Resto del cliente:
Qui il client è un'applicazione mobile Uber a cui l'autista ha effettuato l'accesso. Questa app invia una richiesta all'API REST esposta da Google mappe per ottenere dati in tempo reale. Ad esempio, una richiesta HTTP GET.
Riposo del server:
In questo esempio, Google è il fornitore di servizi e Google L'API di Maps risponde alla richiesta dell'app Uber fornendo i dettagli richiesti.
Sia il client che il server sono ugualmente importanti nella comunicazione REST.
Qui abbiamo implementato esempi per il test di automazione solo del client REST. Per testare il server REST, fare riferimento a https://www.guru99.com/api-testing-tool.html.
Cos'è Restito?
Restito è un framework sviluppato da Mkotsur. È un'app leggera che ti aiuta a eseguire qualsiasi tipo di richiesta HTTP. Puoi usare Restito per testare le tue API REST e per cercare problemi nella tua applicazione o nella tua rete.
Come testare il client REST utilizzando Restito?
Suddividiamo l'esercizio nei seguenti 4 passaggi:
- Crea un client HTTP e un metodo per inviare una richiesta HTTP GET a qualsiasi endpoint del server. Per ora, considera che l'endpoint sia
http://localhost:9092/getevents.
- Avvia un server Restito per ascoltare e acquisire le richieste inviate all'endpoint "getevents" in localhost
http://localhost:9092/getevents.
- Crea una classe di test per testare il client di cui sopra. Richiamare il metodo "sendGETRequest" del client HTTP per avviare una richiesta GET all'API "getevents".
- Convalidare la chiamata HTTP GET utilizzando il framework Restito.
Approfondiamo ciascuno dei passaggi precedenti.
Passo 1) Crea un client HTTP e un metodo per inviare una richiesta HTTP GET a qualsiasi endpoint del server.
========== JAVA CODE inizia ===========
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;
}
}
========== CODICE JAVA Fine ===========
Passo 2) Avvia un server Restito per ascoltare e acquisire le richieste inviate all'endpoint "getevents" in localhost http://localhost:9092/getevents.
========== JAVA CODE inizia ===========
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();
}
}
========== CODICE JAVA Fine ===========
Passo 3) Crea una classe di test per testare il client di cui sopra. Richiamare il metodo sendGETRequest del client HTTP per avviare una richiesta GET all'API "getevents".
========== JAVA CODE inizia ===========
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();
}
}
}
========== CODICE JAVA Fine ===========
Passo 4) Come convalidare la richiesta GET con intestazioni e la richiesta POST con il corpo utilizzando il framework Restito.
========== JAVA CODE inizia ===========
/**
* 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();
}
}
}
}
========== CODICE JAVA Fine ===========
Vantaggi dell'utilizzo di Restito Framework per i test dei client REST
Ecco i vantaggi/vantaggi di Restito Framework per i test dei client ReST
- Non è necessario sviluppare il server REST vero e proprio per testare il client REST.
- Restito fornisce utilità e metodi potenti e vari per simulare il comportamento diverso di un server. Ad esempio: per testare il comportamento del client REST quando il server risponde con un errore HTTP 404 o un errore HTTP 503.
- I server Restito possono essere configurati in pochi millisecondi e possono essere terminati una volta completati i test.
- Restito supporta tutti i tipi di contenuti del metodo HTTP come compresso, non compresso, unificato, applicazione/testo, applicazione/JSON, ecc.
Svantaggi dell'utilizzo di Restito Framework per i test del client REST
Ecco i contro/svantaggi del Restito Framework per i test del client ReST
- L'origine del client REST dovrebbe essere modificata per considerare "localhost" come una macchina server.
- L'apertura del server in qualsiasi porta potrebbe entrare in conflitto se utilizziamo una porta di uso comune come "8080" o "9443" ecc.
- Si consiglia di utilizzare porte come 9092 o 9099, che non sono comunemente utilizzate da altri strumenti.
Sintesi
- REST sta per "REpresentational State Transfer" che è un nuovo modo standard di comunicazione tra due sistemi qualsiasi in un dato momento.
- REST Client è un metodo o uno strumento per richiamare un'API del servizio REST esposta alla comunicazione di qualsiasi sistema o fornitore di servizi.
- Nel metodo RestServer o in un'API esposta per la comunicazione da qualsiasi sistema o provider di servizi.
- Restito è un'app leggera che ti aiuta a eseguire qualsiasi tipo di richiesta HTTP
- Crea un client HTTP e un metodo per inviare una richiesta HTTP GET a qualsiasi endpoint del server
- Avvia un server Restito per ascoltare e acquisire le richieste inviate all'endpoint "getevents".
- Avvia un server Restito per ascoltare e acquisire le richieste inviate all'endpoint "getevents" in localhost
- Qui abbiamo implementato esempi per il test di automazione solo del client REST.
- Non è necessario sviluppare il server REST vero e proprio per testare il client REST.
- L'origine del client REST dovrebbe essere modificata per considerare "localhost" come una macchina server.
