Kiểm tra ứng dụng khách REST bằng Công cụ Restito: Rest Client là gì?

REST là gì?

REST của là viết tắt của “Chuyển giao trạng thái đại diện”, là một cách giao tiếp mới giữa hai hệ thống bất kỳ tại một thời điểm nhất định. Một trong các hệ thống được gọi là 'REST Client' và hệ thống còn lại được gọi là 'REST Server'.

Trước khi tìm hiểu về Restito Framework để thử nghiệm máy khách REST, trước tiên chúng ta hãy tìm hiểu một số điều cơ bản.

Máy khách REST là gì?

Máy khách REST là một phương thức hoặc công cụ để gọi API dịch vụ REST được bất kỳ hệ thống hoặc nhà cung cấp dịch vụ nào cung cấp để liên lạc. Ví dụ: nếu một API được hiển thị để nhận thông tin giao thông theo thời gian thực về một tuyến đường từ Google, thì phần mềm/công cụ gọi API giao thông của Google được gọi là ứng dụng khách REST.

Máy chủ REST là gì?

Đó là một phương thức hoặc một API được bất kỳ hệ thống hoặc nhà cung cấp dịch vụ nào tiếp xúc với nhau. Ví dụ: Google hiển thị API để nhận thông tin giao thông theo thời gian thực trên một tuyến đường nhất định.

Tại đây, máy chủ Google cần được thiết lập và chạy để lắng nghe mọi yêu cầu đối với API được hiển thị từ các máy khách khác nhau.

Ví dụ:

Đã đến lúc thiết lập một kịch bản End-to-End hoàn chỉnh từ các định nghĩa trên.

Chúng ta hãy xem xét một ứng dụng đặt xe taxi như Uber vì một công ty cần thông tin theo thời gian thực về tình hình giao thông xung quanh các tuyến đường mà một phương tiện nhất định đang đi.

Khách hàng nghỉ ngơi:

Ở đây khách hàng là một ứng dụng di động Uber mà tài xế đã đăng nhập. Ứng dụng này gửi yêu cầu tới API REST do Google maps hiển thị để lấy dữ liệu thời gian thực. Ví dụ: Yêu cầu HTTP GET.

Máy chủ nghỉ ngơi:

Trong ví dụ này, Google là Nhà cung cấp dịch vụ và API của Google Maps sẽ phản hồi các thông tin chi tiết cần thiết cho yêu cầu của ứng dụng Uber.

Cả máy khách và máy chủ đều quan trọng như nhau trong giao tiếp REST.

Ở đây, chúng tôi đã triển khai các ví dụ để thử nghiệm tự động hóa chỉ Máy khách REST. Để kiểm tra máy chủ REST, hãy tham khảo https://www.guru99.com/top-6-api-testing-tool.html.

Restito là gì?

Restito là một khuôn khổ được phát triển bởi Mkotsur. Đây là một ứng dụng nhẹ giúp bạn thực hiện bất kỳ loại Yêu cầu HTTP nào. Bạn có thể sử dụng Restito để kiểm tra API REST của mình và tìm kiếm các vấn đề trong ứng dụng hoặc mạng của bạn.

Làm cách nào để kiểm tra ứng dụng khách REST bằng Restito?

Chúng ta hãy chia bài tập thành 4 bước sau:

  1. Tạo một ứng dụng khách HTTP và phương thức để gửi yêu cầu HTTP GET đến bất kỳ điểm cuối máy chủ nào. Hiện tại, hãy coi điểm cuối là http://localhost:9092/getevents.
  1. Khởi động máy chủ Restito để lắng nghe và nắm bắt các yêu cầu được gửi đến điểm cuối 'getevent' trong localhost http://localhost:9092/getevents.
  1. Tạo một lớp thử nghiệm để kiểm tra ứng dụng khách trên. Gọi phương thức 'sendGETRequest' của máy khách HTTP để bắt đầu yêu cầu GET tới 'getevents' API.
  1. Xác thực lệnh gọi HTTP GET bằng khung Restito.

Chúng ta hãy đi sâu vào từng bước trên.

Bước 1) Tạo một ứng dụng khách HTTP và phương thức để gửi yêu cầu HTTP GET đến bất kỳ điểm cuối máy chủ nào.

========== MÃ JAVA Bắt đầu ============

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;
	}
}

========== MÃ JAVA kết thúc ============

Bước 2) Khởi động máy chủ Restito để lắng nghe và nắm bắt các yêu cầu được gửi đến điểm cuối 'getevent' trong localhost http://localhost:9092/getevents.

========== MÃ JAVA Bắt đầu ============

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();
    }


}

========== MÃ JAVA kết thúc ============

Bước 3) Tạo một lớp thử nghiệm để kiểm tra ứng dụng khách trên. Gọi phương thức sendGETRequest của máy khách HTTP để bắt đầu yêu cầu GET tới 'getevent' API.

========== MÃ JAVA Bắt đầu ============
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();
            }
		}	
	}

========== MÃ JAVA kết thúc ============

Bước 4) Cách xác thực yêu cầu GET bằng Tiêu đề và yêu cầu POST với nội dung bằng khung Restito.

========== MÃ JAVA Bắt đầu ============

/**
     * 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();
            }
		}
	}
}

========== MÃ JAVA kết thúc ============

Ưu điểm của việc sử dụng Restito Framework để thử nghiệm máy khách REST

Dưới đây là những ưu/lợi ích của Restito Framework để thử nghiệm máy khách ReST

  • Chúng tôi không cần phát triển máy chủ REST thực tế để kiểm tra Máy khách REST.
  • Restito cung cấp các tiện ích và phương pháp mạnh mẽ và đa dạng để mô phỏng các hành vi khác nhau của Máy chủ. Ví dụ: Để kiểm tra xem máy khách REST hoạt động như thế nào khi Máy chủ phản hồi với lỗi HTTP 404 hoặc lỗi HTTP 503.
  • Máy chủ Restito có thể được thiết lập trong vài mili giây và có thể bị chấm dứt sau khi hoàn tất quá trình kiểm tra.
  • Restito hỗ trợ tất cả các loại nội dung phương thức HTTP như nén, không nén, hợp nhất, ứng dụng/văn bản, ứng dụng/JSON, v.v.

Nhược điểm của việc sử dụng Restito Framework để thử nghiệm máy khách REST

Dưới đây là nhược điểm/nhược điểm của Restito Framework để thử nghiệm máy khách ReST

  • Nguồn máy khách REST phải được điều chỉnh để coi 'localhost' là máy chủ.
  • Việc mở máy chủ ở bất kỳ cổng nào có thể xung đột nếu chúng ta sử dụng một số cổng thường được sử dụng như '8080' hoặc '9443', v.v.
  • Bạn nên sử dụng các cổng như 9092 hoặc 9099, những cổng này không được các công cụ khác sử dụng phổ biến.

Tổng kết

  • REST là viết tắt của “Chuyển giao trạng thái đại diện”, là một cách giao tiếp tiêu chuẩn mới giữa hai hệ thống bất kỳ tại một thời điểm nhất định.
  • Máy khách REST là một phương thức hoặc công cụ để gọi API dịch vụ REST được bất kỳ hệ thống hoặc nhà cung cấp dịch vụ nào tiếp xúc với giao tiếp.
  • Trong phương thức RestServer hoặc một API được hiển thị để liên lạc bởi bất kỳ nhà cung cấp hệ thống hoặc dịch vụ nào.
  • Restito là một ứng dụng nhẹ giúp bạn thực hiện bất kỳ loại Yêu cầu HTTP nào
  • Tạo một ứng dụng khách HTTP và phương thức để gửi yêu cầu HTTP GET đến bất kỳ điểm cuối máy chủ nào
  • Khởi động máy chủ Restito để lắng nghe và nắm bắt các yêu cầu được gửi đến điểm cuối 'getevents'.
  • Khởi động máy chủ Restito để lắng nghe và nắm bắt các yêu cầu được gửi đến điểm cuối 'getevent' trong localhost
  • Ở đây, chúng tôi đã triển khai các ví dụ để thử nghiệm tự động hóa chỉ Máy khách REST.
  • Chúng tôi không cần phát triển máy chủ REST thực tế để kiểm tra Máy khách REST.
  • Nguồn máy khách REST phải được điều chỉnh để coi 'localhost' là máy chủ.