残りのAPIテスト|| RestAssuredチュートリアル2020のクイックガイド

Rest APIテストの自動化のためのRest Assured APIテスト

RestAssured-残りの保証されたチュートリアルAPIテスト
安心のAPI自動化

この徹底的なRestAssuredチュートリアルでは、 詳細なRESTAPIテスト、モジュール化されたアプローチでのRESTAssuredを伴うAPIテスト自動化

RestAssuredとは何ですか?

Rest Assuredは、REST API自動化テストで非常に広く使用されているオープンソーステクノロジーであり、Javaベースのライブラリに基づいています。

RestAssuredはヘッドレスクライアントモードでRestAPIと対話します。異なるレイヤーを追加してリクエストを形成し、サーバーへの異なるHTTPS動詞を介してHTTPリクエストを作成することで、同じリクエストを拡張できます。

Rest Assuredの組み込みライブラリは、ステータスメッセージ、ステータスコード、応答本文など、サーバーから受信した応答の検証を実行するための膨大なメソッドとユーティリティを提供します。

REST API自動化テストのRest Assuredチュートリアルのこの完全なシリーズは、次のトピックで構成されています。

はじめに:ビルドツール(Maven / gradle)を使用したrestAssuredの構成

ステップ1:mavenを使用している場合は、pom.xmlに次の依存関係を追加するだけです(他のバージョンも選択できます)。

REST Assuredの使用を開始するには、プロジェクトに依存関係を追加するだけです。 


    io.rest-assured
    安心してください
    4.3.0
    テスト

Gradleを使用している場合は、build.gradleに次のコードを追加します(ここでも他のバージョンを選択できます)。

testCompileグループ: 'io.rest-assured'、名前: 'rest-assured'、バージョン: '4.3.0'

ステップ2:REST Assuredは、既存の単体テストフレームワーク(Testng、JUnitなど)と非常に簡単に統合して使用できます。

ここでは、ユニットテストフレームワークに関連するtestNgを使用しています。

Rest Assuredのライブラリをインポートしたら、次の静的インポートをテストクラスに追加する必要があります。

import static io.restassured.RestAssured。*;

静的なorg.hamcrest.Matchers。*をインポートします。

注: この今後の学習目的のために、Ergast DeveloperAPIをテストします。 ここで見つけることができる。 このAPIは、F1レース、ドライバー、サーキットなどに関連する履歴データを提供します。

構文に精通している:

Rest AssuredはBDDフォーマットをサポートしています(ガーキン構文)テストスクリプトをGiven / When / Then / And形式で作成するには、BDD / gherkin構文について理解していることを前提としています。そうでない場合は、30分かけてBDD(とは何か)を理解することをお勧めします。ガーキン構文)そしてそれはどのように機能し、その非常に基本的なものです。

T-01: このAPIを使用して1年にF1の回路の数を基本的に検証する最初のスクリプト(http://ergast.com/api/f1/2017/circuits.json)

@Test(description = "2017シーズンのサーキット数は20にする必要があります")public void validatingNumberOfCircuits(){given()。when()。get( "http://ergast.com/api/f1/2017/circuits。 json ")。 then()。assertThat()。body( "MRData.CircuitTable.Circuits.circuitId"、hasSize(20)); }

Rest API応答の検証 :

1.APIリクエストのJSON応答をキャプチャします。

2.GPath式「MRData.CircuitTable.Circuits.circuitId」を使用したcircuitIdのクエリ

3.circuitId要素コレクションのサイズが20であることを確認します

ここでは使用しています ハムクレストマッチャー 次のようなさまざまな検証用

  • equalTo()は同等性を検証します
  • 比較検証のためのlessThan()およびgreaterThan()メソッド、
  • hasItem()メソッドは、要素のコレクションから要素の存在を検証するために使用されます。

特定の検証を実行するのに役立つ他のさまざまな方法があります。

マッチャーとメソッドの完全なリストについては、さらにHamcrestライブラリのドキュメントを参照してください。

応答コードの検証:

Give()。when()。get( "http://ergast.com/api/f1/2017/circuits.json").then()。assertThat()。statusCode(200);

コンテンツタイプの検証

given()。when()。get( "http://ergast.com/api/f1/2017/circuits.json").then()。assertThat()。contentType(ContentType.JSON);

ヘッダー「Content-Length」の検証

Give()。when()。get( "http://ergast.com/api/f1/2017/circuits.json").then()。assertThat()。header(" Content-Length "、equalTo(" 4551 "));

(and()メソッドを使用して)単一のテストでの複数の検証:

@Test(description = "2017シーズンのサーキット数は20にする必要があります")
    public void validatingNumberOfCircuits(){
        Give()。when()。get( "http://ergast.com/api/f1/2017/circuits.json")。then()。assertThat()。header( "Content-Length"、equalTo( " 4551 "))。and()。statusCode(200);
    }

応答本文の要素/属性の検証:

JsonPathを使用してjson属性の値をフェッチし、TestNgを使用してアサーションを配置できます

@Test(description = "f1"であるシリーズ名の検証)
    public void validatingSeriesName(){
        // ResponseBodyを文字列に変換
        文字列responseBody = given()。when()。get( "http://ergast.com/api/f1/2017/circuits.json").getBody()。asString();
        //応答本文を文字列として渡してJsonPathオブジェクトを作成します
        JsonPath resJson = new JsonPath(responseBody);
        // MRDataの下の属性値シリーズを取得します
        String seriesName = resJson.getString( "MRData.series");
        //ユーザーTestNgアサーション
        Assert.assertEquals( "f1"、seriesName);
    }

同様に、XMLPathを使用してXML応答の値を取得できます。ここではJSONを使用しているため、ここでJSonPathを使用しました

RESTful APIは、XNUMXつのタイプのパラメーターのみをサポートします。

A. クエリパラメータ: ここで、パラメーターはAPIエンドポイントの最後に追加され、疑問符で識別でき、次のようなキーと値のペアを形成します。 

https://www.google.com/search?q=https://www.wikipedia.org/

上記のAPIでは、「q」がパラメーターであり、「https://www.wikipedia.org/」がそのパラメーターの値です。SOMETHING_ELSE_TEXT'パラメータの値を置き換えることができます 「q」と 'SOMETHING_ELSE_TEXT'https://www.wikipedia.org/の代わりに。

B. パスパラメータ: これらはRESTful APIエンドポイントの一部です。 

例えば。 以前に使用したエンドポイント:http://ergast.com/api/f1/2017/circuits.json、ここでは「2017」はパスパラメーター値です。

今年の結果を得るには 2016年は2017年を2016年に置き換えることができます その後、APIは2016年の応答本文を提供します。

RestAssuredのパスパラメーターを使用したテスト

@Test(description = "パスパラメータを使用した回路数の検証")
    public void testWithPathParams(){
        文字列seasonNumber = "2017";
       文字列responseBody = given()。pathParam( "season"、seasonNumber).when()。get( "http://ergast.com/api/f1/{season}/circuits.json").getBody()。asString ();
        //応答本文を文字列として渡してJsonPathオブジェクトを作成します
        JsonPath resJson = new JsonPath(responseBody);
        // MRDataの下の属性値シリーズを取得します
        文字列seriesName = resJson.getString( "MRData.series");
        //ユーザーTestNgアサーション
        Assert.assertEquals( "f1"、seriesName);
    }

RestAssuredのクエリパラメーターを使用したテスト

@Test(description = "クエリパラメータを使用したGoogle検索の検証")
    public void testWithPathParams(){
        文字列searchItem = "https://www.wikipedia.org/";
  given()。queryParam( "q"、searchItem).when()。get( "https://www.google.com/search").then()。assertThat()。statusCode(200);
    }

テストのパラメーター化:

Rest Assuredを使用して、データ駆動型テストを実行できます(つまり、同じテストスクリプトが異なる入力データのセットで複数回実行され、異なる出力データを提供します)。 

ステップ1:testNgデータプロバイダーを作成しました。

ステップ2:テストスクリプトでデータプロバイダーを使用します。

@DataProvider(name = "seasonsAndRaceNumbers")
    public Object [] [] testDataFeed(){
        新しいオブジェクトを返す[] [] {
                {"2017"、20}、
                {「2016」、21}
        };
    }
@Test(description = "季節ごとの回路検証の数"、dataProvider = "季節とレース番号")public voidcircuitNumberValidation(文字列seasonYear、int raceNumbers){given()。pathParam( "シーズン"、seasonYear).when()。get( "http://ergast.com/api/f1/{シーズン}/circuits.json ")。then()。assertThat()。body(" MRData.CircuitTable.Circuits.circuitId "、hasSize(レースナンバー)); }

RestAssuredを使用した複数値パラメーターの操作 

複数値パラメーターは、パラメーター名ごとに複数の値を持つパラメーター(つまり、paramKeyごとの値のリスト)です。以下のようにアドレス指定できます。

Give()。param( "paramKey"、 "paramValue1"、 "paramaValue2")。when()。get( "API URL");

または、リストを準備して、そのリストをparamKeyの値として次のように渡すこともできます。

リストparamValue = new new ArrayList ();
paramValue.add(“ paramvalue1”);
paramValue.add(“ paramvalue2);
given()。param( "paramKey"、paramValue).when()。get( "API URL");
RestAssuredを使用したCookieの操作 
given()。cookie( "cookieK"、 "cookieVal")。when()。get( "API URL");

Or 

ここでは、次のように複数値のCookieを指定することもできます。

Give()。cookie( "cookieK"、 "cookieVal1"、 "cookieVal2")。when()。get( "API URL");

ヘッダーの操作:

次のようなヘッダー/ヘッダーを使用してリクエストで指定できます。

Give()。header( "headerK1"、 "headerValue1")。header( "headerK2"、 "headerValue2")。when()。get( "API URL");

contentTypeの操作:

given()。contentType( "application / json")。when()。get( "API URL");

Or 

Give()。contentType(ContentType.JSON).when()。get();

応答時間を測定します。

long timeDurationInSeconds = get(“ API URL”)。timeIn(SECONDS);

RestAPI認証

RESTは、OAuth、ダイジェスト、証明書、フォーム、プリエンプティブな基本認証など、さまざまな認証スキームを保証します。 We either can set authentication for each and every requestリクエストごとに認証を設定することもできます 

これは同じものを使用したサンプルリクエストです:

Give()。auth()。basic( "uName"、 "pwd")。when()。get( "URL")。

一方、認証は、HTTPリクエストに対して以下のアプローチで定義されています。

RestAssured.authentication = basic( "uName"、 "pwd");

基本認証タイプ:

基本認証には、「プリエンプティブ」と「チャレンジドトークン基本認証」のXNUMX種類があります。

プリエンプティブ基本認証:

これにより、特定の状況でサーバーが要求のトリガーとともに不正な応答を行う前でも、基本認証資格情報が送信されるため、追加の接続を確立するためのオーバーヘッドが削減されます。 サーバーがチャレンジする能力をテストしていない限り、これは通常、主に発生する状況です。 

例えば。

Give()。auth()。preemptive()。basic( "uName"、 "pwd")。when()。get( "URL")。then()。statusCode(200);

チャレンジされた基本認証

一方、「チャレンジされた基本認証」REST Assuredは、サーバーが明示的に要求しない限り、つまりサーバーが無許可の応答をスローしない限り、資格情報を提供しません。 その後、UnAuthorized応答Rest-Assuredは、Authである別の要求をサーバーに送信します。

given()。auth()。basic( "uName"、 "pwd")。when()。get( "URL")。then()。statusCode(200);

ダイジェスト認証

現在、「チャレンジドダイジェスト認証」のみが検討されています。 例えば:

Give()。auth()。digest( "uName"、 "pwd")。when()。get( "URL")。then()。statusCode(200); 

フォーム認証

これは、アプリケーション/シナリオに応じて、主に3つの異なるアプローチで実現できます。

フォーム認証はインターネット上で非常に人気のあるもののXNUMXつであり、ユーザーはWebページからユーザー名とパスワードなどの資格情報を入力し、システムにログインします。これは、これを使用して対処できます。 

given()。auth()。form( "uName"、 "pWd")。
when()。get( "URL");
then()。statusCode(200);

これは最適な方法では機能しない可能性があり、Webページの複雑さに応じて合格または不合格になる可能性があります。 以下のアプローチでフォーム認証を設定するときに、これらの詳細を提供することをお勧めします。

given()。auth()。form( "uName"、 "pwd"、new FormAuthConfig( "/ 'mention here form action name that part of the html page code nder the form tag' '、" uName "、" pwd "))。when()。get(" URL ")。then()。statusCode(200);

このアプローチでは、REST Assuredは、追加のリクエストをトリガーしてWebページを解析する必要はありません。 

デフォルトのSpringSecurityを使用している場合は、 事前定義されたFormAuthConfigがトリガーされます。

Give()。auth()。form( "uName"、 "Pwd"、FormAuthConfig.springSecurity())。when()。get( "URL")。then()。statusCode(200);

注:フォーム認証とともに追加の入力データを送信する場合は、次のように記述できます。

given()。auth()。form( "uName"、 "pwd"、formAuthConfig()。withAdditionalFields( "firstInputField"、 "secondInputField")..

CSRF:

CSRFは、クロスサイトリクエストフォージェリの略です。

現在、サーバーがCSRFセキュリティ攻撃を回避するためにCSRFトークンに応答を提供することは非常に一般的です。 REST Assuredは、自動パーサーを使用し、CSRFトークンを提供することでこれをサポートします。 

このRESTアシュアードを達成するには、追加のリクエストを作成し、ウェブサイトを解析する(数少ない)必要があります。

以下のコードを記述することで、CSRFサポートを有効にできます。

Give()。auth()。form( "uName"、 "pwd"、formAuthConfig()。withAutoDetectionOfCsrf())。when()。get( "URL")。then()。statusCode(200);

さらに、REST Assuredを支援し、解析をより完璧で堅牢にするために、CSRFフィールド名を指定できます(ここでは、Spring Securityのデフォルト値を使用し、事前定義されたspringSecurity FormAuthConfigを使用できると想定しています)。

given()。auth()。form( "uName"、 "pwd"、springSecurity()。withCsrfFieldName( "_ csrf"))。when()。get( "URL")。then()。statusCode(200);

デフォルトでは、CSRF値はリクエストとともにフォームパラメータとして渡されますが、必要に応じて以下のようにヘッダーとして送信するように設定できます。

given()。auth()。form( "uName"、 "pwd"、springSecurity()。withCsrfFieldName( "_ csrf")。sendCsrfTokenAsHeader())。when()。get( "URL")。then()。statusCode (200);

OAuth 1:

OAuth 1では、Scribeがクラスパスに含まれている必要があります。 oAuth 1認証を使用するには、次のようにします。

given()。auth()。oauth(..)。when()。 ..

OAuth 2:

given()。auth()。oauth2(accessToken).when()。 ..

上記のアプローチでは、OAuth2accessTokenがヘッダーで考慮されます。 より明確にするために、次のこともできます。

given()。auth()。preemptive()。oauth2(accessToken).when()。 ..

リクエストでのファイル、バイト配列、入力ストリーム、またはテキストの受け渡し:

大量のデータをサーバーに送信する場合、通常、マルチパートフォームデータ手法を使用するのが一般的なアプローチです。 アップロードするファイル、バイト配列、入力ストリーム、またはテキストを指定できるmultiPartと呼ばれるメソッドを提供しますのでご安心ください。 

given()。multiPart(new File( "/ File_Path"))。when()。post( "/ upload");

安心してPOSTリクエストを作成

POSTおよびPUTリクエストでは、データをサーバーに送信し、その基本的にリソースの作成/リソースの更新を行います。これを書き込みまたは更新操作と見なすことができます。

POSTリクエストでサーバーに送信されるデータは、HTTPリクエスト/ API呼び出しの本文で送信されます。 

送信されるコンテンツまたはデータのタイプは、APIに応じて異なる形式にすることができます。つまり、XML、JSON、またはその他の形式はContent-Typeヘッダーによって定義されます。 

POST本体がJSONデータで構成されている場合、ヘッダーContent-Typeはapplication / jsonになります。同様に、XMLで構成されるPOSTリクエストの場合、ヘッダーContent-Typeはapplication / xmlタイプになります。

以下は、同じコードスニペットです。

given()。contentType( "application / json")。param( "pk"、 "pv")。when()。body( "JsonPAyloadString")。post( "url")。then()。assertThat() statusCode(200);

注:文字列(上記のスニペットに示されている)、JsonObject、ファイルなどのように、メソッド「body」内にペイロード/リクエスト本体を渡すには、さまざまな方法があります。

安心のPUTリクエスト:

Give()。contentType( "application / json")。param( "pk"、 "pv")。when()。body( "JsonPAyloadString")。put( "url")。then()。assertThat()。 statusCode(200);

安心してリクエストを削除:

given()。contentType( "application / json")。param( "pk"、 "pv")。when()。delete( "url")。then()。assertThat()。statusCode(200);

そうすれば、さまざまなAPI動詞(GET / POST / PUT / DELETEなど)に対してさまざまなRestAPI呼び出しを作成できます。

Javaでのシリアル化と逆シリアル化:

シリアル化は、基本的にオブジェクトの状態を処理またはバイトストリームに変換することです。 一方、Javaの逆シリアル化は、バイトストリームを処理するか、メモリ内の実際のJavaオブジェクトに変換します。 このメカニズムは、オブジェクトの永続性で使用されます。

以下は同じのブロック図です 

残りのAPIテスト|| RestAssuredチュートリアル2020のクイックガイド

シリアル化の利点

A.オブジェクトの状態を保存/永続化するため。

B.ネットワークを介してオブジェクトをフローする。

JAVAによるシリアライゼーションの実現

直列化可能なJavaオブジェクトを実現するには、java.io.Serializableインターフェースを実装する必要があります。

オブジェクトのシリアル化を担当するwriteObject()メソッドを含むObjectOutputStreamクラス。

ObjectInputStreamクラスには、オブジェクトのデシリアライズを担当するreadObject()という別のメソッドも含まれています。

java.io.Serializableインターフェースを実装しているクラスでは、シリアル化できるオブジェクトのみです。

Serializableは単なるマーカーインターフェイスであり、他のマーケットインターフェイスと同様に、データメンバーやメソッドが関連付けられていません。Javaクラスを「マーク」して、これらのクラスのオブジェクトが特定の機能を取得できるようにするために使用されます。 他のいくつかのマーカーインターフェイスと同様に、次のとおりです。-クローン可能およびリモートなど。

ノート :

1.親クラスがSerializableインターフェースを実装している場合、子クラスはそれを実装する必要はありませんが、その逆は適用されません。

2.非静的データメンバーのみがシリアル化プロセスで保存されます。

3.静的データメンバーと一時データメンバーはシリアル化によって保存されません。したがって、非静的データメンバーの値を保存する必要がない場合は、一時データメンバーにすることができます。

4.オブジェクトが逆シリアル化されるときにコンストラクターが呼び出されることはありません。

ステップ1:最初のステップは、基本的に、Serializableインターフェースを実装するクラスの作成です。

インポートjava.io.Serializable;
パブリッククラスDummyはSerializable {
    プライベートint i;
    プライベート文字列データ。
    public Dummy(int i、String data)
    {
        this.i = 私;
        this.data = data;
    }
}

ステップ2:シリアル化するクラスを作成します。

インポートjava.io.FileNotFoundException;
インポートjava.io.FileOutputStream;
import java.io.IOException;
インポートjava.io.ObjectOutputStream;
パブリッククラスSerialize {
    public static void Serialization(Object classObject、String fileName){
        試して{
            FileOutputStream fileStream = new FileOutputStream(fileName);
            ObjectOutputStream objectStream = new ObjectOutputStream(fileStream);
            objectStream.writeObject(classObject);
            objectStream.close();
            fileStream.close();
        } catch(FileNotFoundException e){
            // TODO自動生成catchブロック
            e.printStackTrace();
        }キャッチ(IOException e){
            // TODO自動生成catchブロック
            e.printStackTrace();
        }
    }
    公共の静的な無効メイン(文字列[] args){
        ダミーdummyObj = new Dummy(10、 "Lambda-geeks");
        Serialization(dummyObj、 "DummSerialized");
    }
}

ステップ3:ステップ2が正常に完了すると、データが含まれているファイルが作成されます。そのデータは、基本的にオブジェクトメンバーのシリアル化されたデータです。

  javaでの逆シリアル化:

以下は、コードスニペットです。

 パブリック静的オブジェクトDeSerialize(String fileName)
    {
        試して{
            FileInputStream fileStream = new FileInputStream(new File(fileName));
            ObjectInputStream objectStream = new ObjectInputStream(fileStream);
            オブジェクトdeserializeObject = objectStream.readObject();
            objectStream.close();
            fileStream.close();
            deserializeObjectを返します。
        } catch(FileNotFoundException e){
            e.printStackTrace();
        }キャッチ(IOException e){
            e.printStackTrace();
        } catch(ClassNotFoundException e){
            e.printStackTrace();
        }
        nullを返します。
    }

ドライバコードは次のようになります。

 公共の静的な無効メイン(文字列[] args){
      / *ダミーdummyObj = new Dummy(10、 "Lambda-geeks");
        Serialization(dummyObj、 "DummSerialized");
        System.out.println( "------------------------------------------- ------------------------------- ");
      */
        ダミーdeSerializedRect =(ダミー)DeSerialize( "DummSerialized");
        System.out.println( "Data From Serialized Object" + deSerializedRect.print());
        System.out.println( "------------------------------------------- ------------------------------- ");
    }

JSONPATHその他の構文/クエリ:

以下のようにJSONを仮定しましょう:

{
  "OrganizationDetails": "組織のダミーの詳細"、
  "地域": "アジア"、
  "Emp-Details":[
    {
      "組織": "ラムダオタク"、
      "情報": {
        "Ph":1234567890、
        "追加": "XYZ"、
        「年齢」:45
      }
    },
    {
      "組織": "lambda-Geeks-2"、
      "情報": {
        "Ph":2134561230、
        "追加": "ABC"、
        「年齢」:35
      }
    }
  ]
}

上記のJSONでは、OrganizationDetails&RegionはLeafノードと呼ばれます。これは、子ノード/要素がそれ以上ないためですが、Emp-Detailsには子ノードがあるため、Leafノードとは呼ばれません。

ここでOrganizationDetailsの値を取得しようとすると、次を使用する必要があります。

$ .OrganizationDetails 
これは次のようになります:
 [
  「組織のダミーの詳細」
]

書く必要のある地域のデータを取得するWiseのように:

$ .Region 

1人目の従業員の年齢の値を見つけたい場合は、次のように記述できます。

$ .Emp-Details [0] .Information.Age
これは次のようになります:
[
  45
]

2人目の従業員の年齢については、次のように書くことができます

$ .Emp-Details [1] .Information.Age
これにより、次のようになります:[35]

このようにして、JsonPath式/クエリを見つけ、JSONの各フィールドのデータをフェッチできます。

デバルギャについて

残りのAPIテスト|| RestAssuredチュートリアル2020のクイックガイド私自身、Debarghya Royです。Fortune5の会社で働いているエンジニアリングアーキテクトであり、さまざまなテクノロジースタックで約12年の経験/専門知識を持つオープンソースコントリビューターです。
Java、C#、Python、Groovy、UIオートメーション(Selenium)、モバイルオートメーション(Appium)、API /バックエンドオートメーション、パフォーマンスエンジニアリング(JMeter、Locust)、セキュリティオートメーション(MobSF、OwAsp、Kali Linuxなど) 、Astra、ZAPなど)、RPA、プロセスエンジニアリングオートメーション、メインフレームオートメーション、SpringBoot、Kafka、Redis、RabitMQ、ELKスタック、GrayLog、Jenkinsを使用したバックエンド開発、およびCloud Technologies、DevOpsなどの経験もあります。
私は妻と一緒にインドのバンガロールに住んでおり、ブログ、音楽、ギターの演奏に情熱を持っています。私の人生哲学は、LambdaGeeks の誕生をもたらした万人のための教育です。 リンクトイン経由で接続できます - https://www.linkedin.com/in/debarghya-roy/

en English
X