REST-kliendi testimine Restito tööriista abil: mis on Rest Client?

Mis on REST?

REST tähistab "esinduslikku seisundiülekannet", mis on uus suhtlusviis mis tahes kahe süsteemi vahel teatud ajahetkel. Ühte süsteemi nimetatakse REST-kliendiks ja teist REST-serveriks.

Enne kui tutvume Restito Framework for REST klienditestimisega, tutvume esmalt mõne põhitõega.

Mis on REST Client?

REST-klient on meetod või tööriist REST-teenuse API kutsumiseks, mis on mis tahes süsteemi või teenusepakkuja jaoks avatud suhtlemiseks. Näiteks: kui API on avatud, et saada Google'ilt marsruudi kohta reaalajas liiklusteavet, nimetatakse Google'i liikluse API-d kutsuvat tarkvara/tööriista REST-kliendiks.

Mis on REST server?

See on meetod või API, millega suhtleb iga süsteem või teenusepakkuja. Näiteks Google avaldab API, et saada reaalajas liiklusteavet antud marsruudil.

Siin peab Google'i server olema töökorras, et kuulata erinevate klientide taotlusi avatud API-le.

Näide:

On aeg koostada ülaltoodud definitsioonide põhjal täielik otsast lõpuni stsenaarium.

Vaatleme takso broneerimisrakendusi nagu Uber, kuna ettevõte vajab reaalajas teavet liiklusolukorra kohta marsruutidel, millel antud sõiduk asub.

Puhke klient:

Siin on kliendiks Uberi mobiilirakendus, kuhu juht on sisse loginud. See rakendus saadab Google Mapsi paljastatud REST API-le päringu, et saada reaalajas andmeid. Näiteks HTTP GET taotlus.

Puhkeserver:

Selles näites on teenusepakkuja Google ja Google Mapsi API vastab Uberi rakenduse päringule nõutavate üksikasjadega.

REST-suhtluses on võrdselt olulised nii klient kui ka server.

Siin oleme rakendanud näiteid ainult REST-kliendi automatiseerimise testimiseks. REST-serveri testimise kohta vt https://www.guru99.com/top-6-api-testing-tool.html.

Mis on Restito?

Restito on Mkotsuri välja töötatud raamistik. See on kerge rakendus, mis aitab teil täita mis tahes HTTP-päringuid. Restito abil saate testida oma REST API-sid ja otsida probleeme oma rakenduses või võrgus.

Kuidas testida REST klienti Restito abil?

Jagame harjutuse järgmiseks 4 sammuks:

  1. Looge HTTP-klient ja meetod HTTP GET-päringu saatmiseks mis tahes serveri lõpp-punktile. Praegu pidage lõpp-punktiks http://localhost:9092/getevents.
  1. Käivitage Restito server, et kuulata ja jäädvustada taotlusi, mis on saadetud kohaliku hosti lõpp-punktile 'getevents' http://localhost:9092/getevents.
  1. Looge ülaltoodud kliendi testimiseks testklass. Käivitage HTTP-kliendi meetod "sendGETRequest", et algatada GET-päring API-le "getevents".
  1. Kinnitage HTTP GET-kõne Restito raamistiku abil.

Sukeldume sügavalt igasse ülaltoodud sammusse.

Step 1) Looge HTTP-klient ja meetod HTTP GET-päringu saatmiseks mis tahes serveri lõpp-punktile.

========== JAVA KOOD Algab ===========

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 KOOD Lõppeb ===========

Step 2) Käivitage Restito server, et kuulata ja jäädvustada taotlusi, mis on saadetud kohaliku hosti lõpp-punktile 'getevents' http://localhost:9092/getevents.

========== JAVA KOOD Algab ===========

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 KOOD Lõppeb ===========

Step 3) Looge ülaltoodud kliendi testimiseks testklass. Käivitage HTTP-kliendi meetod sendGETRequest, et algatada API 'getevents'ile GET-päring.

========== JAVA KOOD Algab ===========
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 KOOD Lõppeb ===========

Step 4) Kuidas kinnitada GET-päring päistega ja POST-päring kehaga, kasutades Restito raamistikku.

========== JAVA KOOD Algab ===========

/**
     * 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 KOOD Lõppeb ===========

Restito Frameworki kasutamise eelised REST-kliendi testimiseks

Siin on Restito Frameworki plussid / eelised ReST-i klientide testimiseks

  • Me ei pea REST-kliendi testimiseks välja töötama tegelikku REST-serverit.
  • Restito pakub tugevaid ja mitmekesiseid utiliite ja meetodeid serveri erineva käitumise pilkamiseks. Näiteks: testimaks, kuidas REST klient käitub, kui server vastab HTTP 404 või HTTP 503 veaga.
  • Restito servereid saab seadistada mõne millisekundiga ja need saab pärast testide lõppu lõpetada.
  • Restito toetab igat tüüpi HTTP-meetodi sisu, nagu tihendatud, tihendamata, ühendatud, rakendus/tekst, rakendus/JSON jne.

Restito Frameworki kasutamise puudused REST-kliendi testimiseks

Siin on Restito Frameworki miinused / puudused ReST kliendi testimiseks

  • REST-kliendi allikat tuleks kohandada, et pidada „localhost” serverimasinaks.
  • Serveri avamine mis tahes pordis võib olla vastuolus, kui kasutame mõnda tavaliselt kasutatavat porti, näiteks '8080' või '9443' jne.
  • Soovitatav on kasutada porte nagu 9092 või 9099, mida teised tööriistad tavaliselt ei kasuta.

kokkuvõte

  • REST tähistab "esinduslikku olekuteavet", mis on uus standardne suhtlusviis mis tahes kahe süsteemi vahel teatud ajahetkel.
  • REST-klient on meetod või tööriist REST-teenuse API kutsumiseks, mis on avatud mis tahes süsteemi või teenusepakkuja suhtlusele.
  • RestServeri meetodil või API-s, mis on mis tahes süsteemi või teenusepakkuja jaoks suhtlemiseks avatud.
  • Restito on kerge rakendus, mis aitab teil täita mis tahes HTTP-päringuid
  • Looge HTTP-klient ja meetod HTTP GET-päringu saatmiseks mis tahes serveri lõpp-punktile
  • Käivitage Restito server, et kuulata ja jäädvustada lõpp-punktile "getevents" saadetud päringuid.
  • Käivitage Restito server, et kuulata ja jäädvustada taotlusi, mis on saadetud kohaliku hosti lõpp-punktile 'getevents'
  • Siin oleme rakendanud näiteid ainult REST-kliendi automatiseerimise testimiseks.
  • Me ei pea REST-kliendi testimiseks välja töötama tegelikku REST-serverit.
  • REST-kliendi allikat tuleks kohandada, et pidada „localhost” serverimasinaks.