REST-Client-Tests mit dem Restito-Tool: Was ist Rest-Client?

Was ist REST?

REST steht für „REpresentational State Transfer“, eine neue Art der Kommunikation zwischen zwei beliebigen Systemen zu einem bestimmten Zeitpunkt. Eines der Systeme heißt „REST Client“, das andere „REST Server“.

Bevor wir uns mit dem Restito Framework für REST-Client-Tests vertraut machen, lernen wir zunächst ein paar Grundlagen kennen.

Was ist ein REST-Client?

Der REST-Client ist eine Methode oder ein Tool zum Aufrufen einer REST-Service-API, die von jedem System oder Serviceanbieter für die Kommunikation bereitgestellt wird. Beispiel: Wenn eine API verfügbar gemacht wird, um Echtzeit-Verkehrsinformationen über eine Route von Google zu erhalten, wird die Software/das Tool, die die Google-Verkehrs-API aufruft, als REST-Client bezeichnet.

Was ist ein REST-Server?

Es handelt sich um eine Methode oder API, die von jedem System oder Dienstanbieter für die Kommunikation bereitgestellt wird. Beispielsweise stellt Google eine API bereit, um Verkehrsinformationen auf einer bestimmten Route in Echtzeit abzurufen.

Hier muss der Google-Server betriebsbereit sein, um alle Anfragen verschiedener Clients an die offengelegte API abzuhören.

Beispiel:

Es ist an der Zeit, aus den oben genannten Definitionen ein vollständiges End-to-End-Szenario zu erstellen.

Betrachten wir Taxi-Buchungsanwendungen wie Uber, da ein Unternehmen Echtzeitinformationen über die Verkehrssituation auf den Strecken benötigt, auf denen sich ein bestimmtes Fahrzeug befindet.

Rest-Client:

Hier ist der Client eine mobile Uber-Anwendung, bei der sich der Fahrer angemeldet hat. Diese App sendet eine Anfrage an die von Google Maps bereitgestellte REST-API, um die Echtzeitdaten abzurufen. Zum Beispiel eine HTTP-GET-Anfrage.

Restserver:

In diesem Beispiel ist Google der Dienstanbieter und die API von Google Maps antwortet mit den erforderlichen Details auf die Anfrage der Uber-App.

Sowohl der Client als auch der Server sind bei der REST-Kommunikation gleichermaßen wichtig.

Hier haben wir Beispiele für Automatisierungstests nur des REST-Clients implementiert. Informationen zum Testen des REST-Servers finden Sie unter https://www.guru99.com/top-6-api-testing-tool.html.

Was ist Restito?

Restito ist ein von Mkotsur entwickeltes Framework. Es ist eine leichtgewichtige App, die Ihnen bei der Ausführung jeder Art von HTTP-Anforderung hilft. Sie können Restito verwenden, um Ihre REST-APIs zu testen und nach Problemen in Ihrer Anwendung oder Ihrem Netzwerk zu suchen.

Wie teste ich den REST-Client mit Restito?

Teilen wir die Übung in die folgenden 4 Schritte auf:

  1. Erstellen Sie einen HTTP-Client und eine Methode zum Senden einer HTTP-GET-Anfrage an einen beliebigen Serverendpunkt. Betrachten Sie zunächst den Endpunkt als http://localhost:9092/getevents.
  1. Starten Sie einen Restito-Server, um die an den Endpunkt „getevents“ in localhost gesendeten Anforderungen abzuhören und zu erfassen http://localhost:9092/getevents.
  1. Erstellen Sie eine Testklasse, um den oben genannten Client zu testen. Rufen Sie die HTTP-Client-Methode „sendGETRequest“ auf, um eine GET-Anfrage an die API „getevents“ zu initiieren.
  1. Validieren Sie den HTTP-GET-Aufruf mit dem Restito-Framework.

Lassen Sie uns tief in jeden der oben genannten Schritte eintauchen.

Schritt 1) Erstellen Sie einen HTTP-Client und eine Methode zum Senden einer HTTP-GET-Anfrage an einen beliebigen Serverendpunkt.

========== JAVA CODE Startet ===========

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 CODE endet ===========

Schritt 2) Starten Sie einen Restito-Server, um die an den Endpunkt „getevents“ in localhost gesendeten Anforderungen abzuhören und zu erfassen http://localhost:9092/getevents.

========== JAVA CODE Startet ===========

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 CODE endet ===========

Schritt 3) Erstellen Sie eine Testklasse, um den oben genannten Client zu testen. Rufen Sie die sendGETRequest-Methode des HTTP-Clients auf, um eine GET-Anfrage an die API „getevents“ zu initiieren.

========== JAVA CODE Startet ===========
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 CODE endet ===========

Schritt 4) So validieren Sie eine GET-Anfrage mit Headern und eine POST-Anfrage mit dem Text mithilfe des Restito-Frameworks.

========== JAVA CODE Startet ===========

/**
     * 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 CODE endet ===========

Vorteile der Verwendung von Restito Framework für REST-Client-Tests

Hier sind die Vor- und Vorteile des Restito Framework für ReST-Clienttests

  • Zum Testen des REST-Clients muss nicht der eigentliche REST-Server entwickelt werden.
  • Restito bietet leistungsstarke und vielfältige Dienstprogramme und Methoden, um das unterschiedliche Verhalten eines Servers zu simulieren. Beispiel: Um zu testen, wie sich der REST-Client verhält, wenn der Server mit einem HTTP 404- oder HTTP 503-Fehler antwortet.
  • Restito-Server können in wenigen Millisekunden eingerichtet und nach Abschluss der Tests beendet werden.
  • Restito unterstützt alle Arten von HTTP-Methodeninhalten wie komprimiert, nicht komprimiert, einheitlich, Anwendung/Text, Anwendung/JSON usw.

Nachteile der Verwendung des Restito Framework für REST-Client-Tests

Hier sind die Vor- und Nachteile des Restito Framework für ReST-Clienttests

  • Die REST-Client-Quelle sollte so angepasst werden, dass sie „localhost“ als Servermaschine betrachtet.
  • Das Öffnen des Servers an einem beliebigen Port kann zu Konflikten führen, wenn wir einen häufig verwendeten Port wie „8080“ oder „9443“ usw. verwenden.
  • Es wird empfohlen, Ports wie 9092 oder 9099 zu verwenden, die von anderen Tools normalerweise nicht verwendet werden.

Zusammenfassung

  • REST steht für „REpresentational State Transfer“ und ist eine neue Standardmethode für die Kommunikation zwischen zwei beliebigen Systemen zu einem bestimmten Zeitpunkt.
  • Der REST-Client ist eine Methode oder ein Tool zum Aufrufen einer REST-Service-API, die von jedem System oder Serviceanbieter für die Kommunikation bereitgestellt wird.
  • In der RestServer-Methode oder einer API, die für die Kommunikation durch jedes System oder jeden Dienstanbieter verfügbar gemacht wird.
  • Restito ist eine leichtgewichtige App, die Sie bei der Ausführung jeder Art von HTTP-Anfrage unterstützt
  • Erstellen Sie einen HTTP-Client und eine Methode zum Senden einer HTTP-GET-Anfrage an einen beliebigen Serverendpunkt
  • Starten Sie einen Restito-Server, um die an den Endpunkt „getevents“ gesendeten Anforderungen abzuhören und zu erfassen.
  • Starten Sie einen Restito-Server, um die an den Endpunkt „getevents“ in localhost gesendeten Anforderungen abzuhören und zu erfassen
  • Hier haben wir Beispiele für Automatisierungstests nur des REST-Clients implementiert.
  • Zum Testen des REST-Clients muss nicht der eigentliche REST-Server entwickelt werden.
  • Die REST-Client-Quelle sollte so angepasst werden, dass sie „localhost“ als Servermaschine betrachtet.