Testiranje REST klijenta pomoću alata Restito: Što je Rest klijent?
Što je REST?
OSTALO označava "REpresentational State Transfer", što je novi način komunikacije između bilo koja dva sustava u određenom trenutku. Jedan od sustava zove se 'REST klijent', a drugi 'REST poslužitelj'.
Prije nego što naučimo Restito Framework za testiranje REST klijenta, prvo naučimo nekoliko osnova.
Što je REST klijent?
REST klijent je metoda ili alat za pozivanje REST servisnog API-ja koji je dostupan za komunikaciju bilo kojem sustavu ili pružatelju usluga. Na primjer: ako je API dostupan za dobivanje informacija o prometu u stvarnom vremenu o ruti iz Google, softver/alat koji poziva Google API za promet naziva se REST klijent.
Što je REST poslužitelj?
To je metoda ili API koji je izložen komunikaciji bilo kojeg sustava ili pružatelja usluga. Na primjer, Google pruža API za dobivanje informacija o prometu u stvarnom vremenu na određenoj ruti.
Evo, Google Poslužitelj mora biti pokrenut i raditi kako bi mogao slušati sve zahtjeve izloženom API-ju od različitih klijenata.
Primjer:
Vrijeme je da uspostavimo potpuni scenarij od kraja do kraja prema gornjim definicijama.
Razmotrimo aplikacije za rezervaciju taksija kao što je Uber jer tvrtka treba informacije u stvarnom vremenu o prometnoj situaciji oko ruta na kojima se nalazi određeno vozilo.
Odmori klijenta:
Ovdje je klijent Uberova mobilna aplikacija na koju se vozač prijavio. Ova aplikacija šalje zahtjev REST API-ju koji je izložen od strane Google karte za dobivanje podataka u stvarnom vremenu. Na primjer, HTTP GET zahtjev.
Poslužitelj za odmor:
U ovom primjeru Google je Pružatelj usluga i Google API mapa odgovara s potrebnim detaljima na zahtjev Uber aplikacije.
I klijent i poslužitelj jednako su važni u REST komunikaciji.
Ovdje smo implementirali primjere za automatizirano testiranje samo REST klijenta. Za testiranje REST poslužitelja pogledajte https://www.guru99.com/api-testing-tool.html.
Što je Restito?
Restito je okvir koji je razvio Mkotsur. To je lagana aplikacija koja vam pomaže izvršiti bilo koju vrstu HTTP zahtjeva. Restito možete koristiti za testiranje svojih REST API-ja i za pretraživanje problema u vašoj aplikaciji ili mreži.
Kako testirati REST klijent koristeći Restito?
Podijelimo vježbu u sljedeća 4 koraka:
- Stvorite HTTP klijenta i metodu za slanje HTTP GET zahtjeva bilo kojoj krajnjoj točki poslužitelja. Za sada krajnju točku smatrajte
http://localhost:9092/getevents.
- Pokrenite Restito poslužitelj za slušanje i snimanje zahtjeva poslanih krajnjoj točki 'getevents' u localhost
http://localhost:9092/getevents.
- Napravite testnu klasu za testiranje gore navedenog klijenta. Pozovite metodu 'sendGETRequest' HTTP klijenta za pokretanje GET zahtjeva za API 'getevents'.
- Provjeri valjanost HTTP GET poziva pomoću okvira Restito.
Zaronimo duboko u svaki od gore navedenih koraka.
Korak 1) Stvorite HTTP klijenta i metodu za slanje HTTP GET zahtjeva bilo kojoj krajnjoj točki poslužitelja.
========== JAVA KOD Počinje ============
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;
}
}
========== JAVA KOD završava ===========
Korak 2) Pokrenite Restito poslužitelj za slušanje i snimanje zahtjeva poslanih krajnjoj točki 'getevents' u localhost http://localhost:9092/getevents.
========== JAVA KOD Počinje ============
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();
}
}
========== JAVA KOD završava ===========
Korak 3) Napravite testnu klasu za testiranje gore navedenog klijenta. Pozovite HTTP klijentsku metodu sendGETRequest da biste pokrenuli GET zahtjev za API 'getevents'.
========== JAVA KOD Počinje ============
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();
}
}
}
========== JAVA KOD završava ===========
Korak 4) Kako potvrditi GET zahtjev sa zaglavljima i POST zahtjev sa tijelom koristeći Restito okvir.
========== JAVA KOD Počinje ============
/**
* 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();
}
}
}
}
========== JAVA KOD završava ===========
Prednosti korištenja Restito Frameworka za testiranje REST klijenta
Ovdje su prednosti/prednosti Restito Frameworka za ReST klijentsko testiranje
- Ne trebamo razvijati stvarni REST poslužitelj za testiranje REST klijenta.
- Restito pruža jake i raznolike alate i metode za ismijavanje različitog ponašanja poslužitelja. Na primjer: Za testiranje kako se REST klijent ponaša kada poslužitelj odgovori s HTTP 404 pogreškom ili HTTP 503 pogreškom.
- Restito poslužitelji mogu se postaviti u nekoliko milisekundi i mogu se prekinuti nakon završetka testova.
- Restito podržava sve vrste sadržaja HTTP metoda kao što su komprimirani, nekomprimirani, unificirani, aplikacija/tekst, aplikacija/JSON itd.
Nedostaci korištenja Restito Frameworka za testiranje REST klijenta
Ovdje su mane/mane Restito Frameworka za testiranje ReST klijenta
- Izvor REST klijenta trebao bi se prilagoditi da se 'localhost' smatra poslužiteljskim strojem.
- Otvaranje poslužitelja u bilo kojem portu može biti u sukobu ako koristimo neki često korišteni port poput '8080' ili '9443' itd.
- Savjetuje se korištenje priključaka poput 9092 ili 9099, koji se obično ne koriste u drugim alatima.
Rezime
- REST je kratica za "REpresentational State Transfer" što je novi standardni način komunikacije između bilo koja dva sustava u određenom trenutku.
- REST klijent je metoda ili alat za pozivanje API-ja REST usluge koji je izložen komunikaciji bilo kojeg sustava ili pružatelja usluga.
- U RestServer metodi ili API-ju koji je izložen komunikaciji bilo kojeg sustava ili pružatelja usluga.
- Restito je lagana aplikacija koja vam pomaže izvršiti bilo koju vrstu HTTP zahtjeva
- Stvorite HTTP klijenta i metodu za slanje HTTP GET zahtjeva bilo kojoj krajnjoj točki poslužitelja
- Pokrenite Restito poslužitelj za slušanje i hvatanje zahtjeva poslanih krajnjoj točki 'getevents'.
- Pokrenite Restito poslužitelj za slušanje i snimanje zahtjeva poslanih krajnjoj točki 'getevents' u localhost
- Ovdje smo implementirali primjere za automatizirano testiranje samo REST klijenta.
- Ne trebamo razvijati stvarni REST poslužitelj za testiranje REST klijenta.
- Izvor REST klijenta trebao bi se prilagoditi da se 'localhost' smatra poslužiteljskim strojem.
