Restito ツールを使用した REST クライアント テスト: Rest クライアントとは何ですか?
RESTとは何ですか?
REST 「REpresentational State Transfer」の略で、特定の時点での XNUMX つのシステム間の新しい通信方法です。 一方のシステムは「REST クライアント」と呼ばれ、もう一方のシステムは「REST サーバー」と呼ばれます。
REST クライアント テスト用の Restito フレームワークについて学ぶ前に、まずいくつかの基本を学びましょう。
RESTクライアントとは何ですか?
REST クライアントは、任意のシステムまたはサービス プロバイダーによる通信用に公開されている REST サービス API を呼び出すためのメソッドまたはツールです。 たとえば、Google からルートに関するリアルタイムの交通情報を取得するために API が公開されている場合、Google 交通 API を呼び出すソフトウェア/ツールは REST クライアントと呼ばれます。
RESTサーバーとは何ですか?
これは、システムまたはサービス プロバイダーによって通信に公開されるメソッドまたは API です。 たとえば、Google は、特定のルート上のリアルタイムの交通情報を取得する API を公開しています。
ここで、さまざまなクライアントから公開された API へのリクエストをリッスンするには、Google サーバーが稼働している必要があります。
例:
上記の定義に基づいて、完全なエンドツーエンドのシナリオを確立するときが来ました。
企業は特定の車両が位置するルート周辺の交通状況に関するリアルタイムの情報を必要としているため、Uber のようなタクシー予約アプリケーションを考えてみましょう。
残りのクライアント:
ここでのクライアントは、ドライバーがログオンしている Uber モバイル アプリケーションです。 このアプリは、Google マップによって公開されている REST API にリクエストを送信して、リアルタイム データを取得します。 たとえば、HTTP GET リクエストです。
レストサーバー:
この例では、Google がサービス プロバイダーであり、Google マップの API が Uber アプリのリクエストに必要な詳細を返します。
REST 通信では、クライアントとサーバーの両方が同様に重要です。
ここでは、REST クライアントのみの自動テストの例を実装しました。 RESTサーバーのテストについては、以下を参照してください。 https://www.guru99.com/top-6-api-testing-tool.html.
レストシートとは何ですか?
Restito は、Mkotsur によって開発されたフレームワークです。あらゆる種類の HTTP リクエストの実行を支援する軽量アプリです。Restito を使用して、REST API をテストしたり、アプリケーションやネットワークの問題を検索したりできます。
Restitoを使用してRESTクライアントをテストするにはどうすればよいですか?
この演習を次の 4 つのステップに分けてみましょう。
- HTTP クライアントとメソッドを作成して、任意のサーバー エンドポイントに HTTP GET リクエストを送信します。 現時点では、エンドポイントを次のように考えます。
http://localhost:9092/getevents
.
- Restito サーバーを起動して、ローカルホストのエンドポイント「getevents」に送信されたリクエストをリッスンしてキャプチャします。
http://localhost:9092/getevents
.
- 上記のクライアントをテストするためのテストクラスを作成します。 HTTP クライアントの「sendGETRequest」メソッドを呼び出して、API「getevents」への GET リクエストを開始します。
- Restito フレームワークを使用して HTTP GET 呼び出しを検証します。
上記の各ステップを詳しく見てみましょう。
ステップ1) HTTP クライアントとメソッドを作成して、任意のサーバー エンドポイントに HTTP GET リクエストを送信します。
========== JAVA コードの開始 ===========
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 コードは終了 ===========
ステップ2) Restito サーバーを起動して、ローカルホストのエンドポイント「getevents」に送信されたリクエストをリッスンしてキャプチャします。 http://localhost:9092/getevents
.
========== JAVA コードの開始 ===========
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 コードは終了 ===========
ステップ3) 上記のクライアントをテストするためのテストクラスを作成します。 HTTP クライアントの sendGETRequest メソッドを呼び出して、API 'getevents' への GET リクエストを開始します。
========== JAVA コードの開始 ===========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 コードは終了 ===========
ステップ4) Restito フレームワークを使用して、ヘッダーを含む GET リクエストと本文を含む POST リクエストを検証する方法。
========== JAVA コードの開始 ===========
/** * 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 コードは終了 ===========
REST クライアント テストに Restito Framework を使用する利点
ReSTクライアントテスト用のRestito Frameworkの長所/利点は次のとおりです
- REST クライアントをテストするために実際の REST サーバーを開発する必要はありません。
- Restito は、サーバーのさまざまな動作をモックするための強力で多様なユーティリティとメソッドを提供します。例: サーバーが HTTP 404 エラーまたは HTTP 503 エラーで応答したときに REST クライアントがどのように動作するかをテストします。
- Restito サーバーは数ミリ秒でセットアップでき、テスト完了後に終了できます。
- Restito は、圧縮、非圧縮、統合、アプリケーション/テキスト、アプリケーション/JSON など、あらゆるタイプの HTTP メソッド コンテンツをサポートします。
REST クライアント テストに Restito Framework を使用するデメリット
ReSTクライアントテスト用のRestitoフレームワークの短所/欠点は次のとおりです
- REST クライアント ソースを調整して、「localhost」をサーバー マシンとして考慮する必要があります。
- 「8080」や「9443」などの一般的に使用されるポートを使用すると、任意のポートでサーバーを開くと競合する可能性があります。
- 他のツールでは一般的に使用されない 9092 や 9099 などのポートを使用することをお勧めします。
まとめ
- REST は「REpresentational State Transfer」の略で、特定の時点での XNUMX つのシステム間の通信の新しい標準方法です。
- REST クライアントは、任意のシステムまたはサービス プロバイダーによる通信に公開される REST サービス API を呼び出すためのメソッドまたはツールです。
- RestServer メソッド、またはシステムまたはサービス プロバイダーによって通信用に公開される API。
- Restito は、あらゆる種類の HTTP リクエストの実行を支援する軽量アプリです。
- HTTP クライアントとメソッドを作成して、任意のサーバー エンドポイントに HTTP GET リクエストを送信します。
- Restito サーバーを起動して、エンドポイント「getevents」に送信されたリクエストをリッスンしてキャプチャします。
- Restito サーバーを起動して、ローカルホストのエンドポイント「getevents」に送信されたリクエストをリッスンしてキャプチャします。
- ここでは、REST クライアントのみの自動テストの例を実装しました。
- REST クライアントをテストするために実際の REST サーバーを開発する必要はありません。
- REST クライアント ソースを調整して、「localhost」をサーバー マシンとして考慮する必要があります。