Test du client REST à l'aide de l'outil Restito : qu'est-ce que Rest Client ?
Qu'est-ce que le REPOS ?
REST signifie « REpresentational State Transfer », qui est un nouveau moyen de communication entre deux systèmes quelconques à un moment donné. L'un des systèmes s'appelle « Client REST » et l'autre « Serveur REST ».
Avant d'en savoir plus sur Restito Framework pour les tests des clients REST, apprenons d'abord quelques bases.
Qu'est-ce que le client REST ?
Le client REST est une méthode ou un outil permettant d'appeler une API de service REST exposée pour la communication par n'importe quel système ou fournisseur de services. Par exemple : si une API est exposée pour obtenir des informations de trafic en temps réel sur un itinéraire de Google, le logiciel/outil qui appelle l'API de trafic de Google est appelé client REST.
Qu'est-ce que le serveur REST ?
Il s'agit d'une méthode ou d'une API exposée à la communication par n'importe quel système ou fournisseur de services. Par exemple, Google expose une API pour obtenir des informations sur le trafic en temps réel sur un itinéraire donné.
Ici, le serveur Google doit être opérationnel pour écouter toutes les requêtes adressées à l'API exposée provenant de différents clients.
Mise en situation :
Il est temps d’établir un scénario complet de bout en bout à partir des définitions ci-dessus.
Considérons une application de réservation de taxi comme Uber, car une entreprise a besoin d'informations en temps réel sur la situation du trafic autour des itinéraires sur lesquels se trouve un véhicule donné.
Client de repos :
Ici, le client est une application mobile Uber à laquelle le conducteur s'est connecté. Cette application envoie une requête à l'API REST exposée par Google Maps pour obtenir les données en temps réel. Par exemple, une requête HTTP GET.
Serveur de repos :
Dans cet exemple, Google est le fournisseur de services et l'API de Google Maps répond avec les détails requis à la demande de l'application Uber.
Le client et le serveur sont tout aussi importants dans la communication REST.
Ici, nous avons implémenté des exemples pour les tests d'automatisation du client REST uniquement. Pour tester le serveur REST, reportez-vous à https://www.guru99.com/top-6-api-testing-tool.html.
Qu’est-ce que Restito?
Restito est un framework développé par Mkotsur. Il s'agit d'une application légère pour vous aider à exécuter tout type de requête HTTP. Vous pouvez utiliser Restito pour tester vos API REST et rechercher des problèmes dans votre application ou votre réseau.
Comment tester le client REST avec Restito ?
Divisons l'exercice en 4 étapes suivantes :
- Créez un client HTTP et une méthode pour envoyer une requête HTTP GET à n'importe quel point de terminaison du serveur. Pour l'instant, considérons que le point final est
http://localhost:9092/getevents
.
- Démarrez un serveur Restito pour écouter et capturer les requêtes envoyées au point de terminaison « getevents » dans localhost
http://localhost:9092/getevents
.
- Créez une classe de test pour tester le client ci-dessus. Invoquez la méthode « sendGETRequest » du client HTTP pour lancer une requête GET à l'API « getevents ».
- Validez l'appel HTTP GET à l'aide du framework Restito.
Examinons en profondeur chacune des étapes ci-dessus.
Étape 1) Créez un client HTTP et une méthode pour envoyer une requête HTTP GET à n'importe quel point de terminaison du serveur.
========== LE CODE JAVA démarre ===========
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; } }
========== Fin du CODE JAVA ===========
Étape 2) Démarrez un serveur Restito pour écouter et capturer les requêtes envoyées au point de terminaison « getevents » dans localhost http://localhost:9092/getevents
.
========== LE CODE JAVA démarre ===========
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(); } }
========== Fin du CODE JAVA ===========
Étape 3) Créez une classe de test pour tester le client ci-dessus. Invoquez la méthode sendGETRequest du client HTTP pour lancer une requête GET à l'API « getevents ».
========== LE CODE JAVA démarre ===========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(); } } }
========== Fin du CODE JAVA ===========
Étape 4) Comment valider la requête GET avec les en-têtes et la requête POST avec le corps à l'aide du framework Restito.
========== LE CODE JAVA démarre ===========
/** * 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(); } } } }
========== Fin du CODE JAVA ===========
Avantages de l'utilisation de Restito Framework pour les tests des clients REST
Voici les avantages/avantages de Restito Framework pour les tests clients ReST
- Nous n'avons pas besoin de développer le serveur REST réel pour tester le client REST.
- Restito fournit des utilitaires et des méthodes puissants et variés pour simuler différents comportements d'un serveur. Par exemple : pour tester le comportement du client REST lorsque le serveur répond avec une erreur HTTP 404 ou une erreur HTTP 503.
- Les serveurs Restito peuvent être configurés en quelques millisecondes et peuvent être arrêtés une fois les tests terminés.
- Restito prend en charge tous les types de contenu de méthode HTTP comme compressé, non compressé, unifié, application/texte, application/JSON, etc.
Inconvénients de l'utilisation de Restito Framework pour les tests des clients REST
Voici les inconvénients/inconvénients de Restito Framework pour les tests clients ReST
- La source du client REST doit être modifiée pour considérer « localhost » comme une machine serveur.
- L'ouverture du serveur sur n'importe quel port peut entrer en conflit si nous utilisons un port couramment utilisé comme « 8080 » ou « 9443 », etc.
- Il est conseillé d'utiliser des ports comme 9092 ou 9099, qui ne sont pas couramment utilisés par d'autres outils.
Résumé
- REST signifie « REpresentational State Transfer », qui est un nouveau moyen standard de communication entre deux systèmes à un moment donné.
- Le client REST est une méthode ou un outil permettant d'invoquer une API de service REST exposée à la communication par n'importe quel système ou fournisseur de services.
- Dans la méthode RestServer ou une API exposée pour la communication par tout système ou fournisseur de services.
- Restito est une application légère pour vous aider à exécuter tout type de requête HTTP
- Créez un client HTTP et une méthode pour envoyer une requête HTTP GET à n'importe quel point de terminaison du serveur
- Démarrez un serveur Restito pour écouter et capturer les requêtes envoyées au point de terminaison « getevents ».
- Démarrez un serveur Restito pour écouter et capturer les requêtes envoyées au point de terminaison « getevents » dans localhost
- Ici, nous avons implémenté des exemples pour les tests d'automatisation du client REST uniquement.
- Nous n'avons pas besoin de développer le serveur REST réel pour tester le client REST.
- La source du client REST doit être modifiée pour considérer « localhost » comme une machine serveur.