1. 序章

REST-assuredは、REST APIのテストと検証を簡素化するように設計されており、RubyやGroovyなどの動的言語で使用されるテスト手法の影響を強く受けます。

ライブラリは、もちろん動詞と標準のHTTP操作から始めて、HTTPをしっかりとサポートしていますが、これらの基本をはるかに超えています。

このガイドでは、 REST-assured を探索し、Hamcrestを使用してアサーションを実行します。 Hamcrestにまだ慣れていない場合は、最初にチュートリアルHamcrestを使用してブラッシュアップする必要があります。

また、REST-assuredのより高度なユースケースについては、他の記事をご覧ください。

それでは、簡単な例を見てみましょう。

2. 簡単なテスト例

始める前に、テストに次の静的インポートがあることを確認しましょう。

io.restassured.RestAssured.*
io.restassured.matcher.RestAssuredMatchers.*
org.hamcrest.Matchers.*

テストをシンプルに保ち、メインAPIに簡単にアクセスできるようにするために必要です。

それでは、簡単な例から始めましょう。ゲームのデータを公開する基本的な賭けシステムです。

{
    "id": "390",
    "data": {
        "leagueId": 35,
        "homeTeam": "Norway",
        "visitingTeam": "England",
    },
    "odds": [{
        "price": "1.30",
        "name": "1"
    },
    {
        "price": "5.25",
        "name": "X"
    }]
}

これが、ローカルにデプロイされたAPIをヒットしたときのJSON応答であるとしましょう– http:// localhost:8080 / events?id=390。

ここで、REST-assuredを使用して、応答JSONのいくつかの興味深い機能を検証しましょう。

@Test
public void givenUrl_whenSuccessOnGetsResponseAndJsonHasRequiredKV_thenCorrect() {
   get("/events?id=390").then().statusCode(200).assertThat()
      .body("data.leagueId", equalTo(35)); 
}

つまり、ここで行ったことは、エンドポイント / events?id =390への呼び出しがJSON文字列を含む本文で応答することを確認したことです。この本文にはleagueId dataオブジェクトのは35です。

もっと興味深い例を見てみましょう。 odds配列に価格1.30および5.25のレコードがあることを確認するとします。

@Test
public void givenUrl_whenJsonResponseHasArrayWithGivenValuesUnderKey_thenCorrect() {
   get("/events?id=390").then().assertThat()
      .body("odds.price", hasItems("1.30", "5.25"));
}

3. RESTで保証されたセットアップ

お気に入りの依存関係ツールがMavenの場合、pom.xmlファイルに次の依存関係を追加します。

<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <version>3.3.0</version>
    <scope>test</scope>
</dependency>

最新バージョンを入手するには、このリンクをたどってください。 REST-assuredは、Hamcrestマッチャーの能力を利用してアサーションを実行するため、その依存関係も含める必要があります。

<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-all</artifactId>
    <version>2.1</version>
</dependency>

最新バージョンは常にこのリンクで入手できます。

4. 匿名JSONルート検証

オブジェクトではなくプリミティブで構成される配列について考えてみます。

[1, 2, 3]

これは匿名JSONルートと呼ばれます。つまり、キーと値のペアはありませんが、それでも有効なJSONデータです。

このようなシナリオでは、 $ シンボルまたは空の文字列( “”)をパスとして使用して検証を実行できます。 上記のサービスをhttp:// localhost:8080 / json を介して公開すると仮定すると、REST-assuredを使用して次のように検証できます。

when().get("/json").then().body("$", hasItems(1, 2, 3));

またはこのように:

when().get("/json").then().body("", hasItems(1, 2, 3));

5. フロートとダブルス

RESTサービスをテストするためにREST-assuredを使い始めるとき、JSON応答の浮動小数点数がプリミティブ型float。にマップされることを理解する必要があります。

float タイプの使用は、Javaの多くのシナリオの場合のように、doubleと互換性がありません。

適切な例は、この応答です。

{
    "odd": {
        "price": "1.30",
        "ck": 12.2,
        "name": "1"
    }
}

ckの値に対して次のテストを実行していると仮定します。

get("/odd").then().assertThat().body("odd.ck", equalTo(12.2));

テストしている値が応答の値と等しい場合でも、このテストは失敗します。 これは、floatではなくdoubleと比較しているためです。

これを機能させるには、equalToマッチャーメソッドのオペランドをfloatとして明示的に指定する必要があります。

get("/odd").then().assertThat().body("odd.ck", equalTo(12.2f));

6. リクエスト方法の指定

通常、使用するリクエストメソッドに対応する get()、などのメソッドを呼び出してリクエストを実行します。

さらに、 request()メソッドを使用してHTTP動詞を指定することもできます。

@Test
public void whenRequestGet_thenOK(){
    when().request("GET", "/users/eugenp").then().statusCode(200);
}

上記の例は、 get()を直接使用するのと同じです。

同様に、 HEAD CONNECT 、およびOPTIONSリクエストを送信できます。

@Test
public void whenRequestHead_thenOK() {
    when().request("HEAD", "/users/eugenp").then().statusCode(200);
}

POST リクエストも同様の構文に従い、 with()および body()メソッドを使用して本体を指定できます。

したがって、 POST リクエストを送信して、新しい奇数を作成するには、次のようにします。

@Test
public void whenRequestedPost_thenCreated() {
    with().body(new Odd(5.25f, 1, 13.1f, "X"))
      .when()
      .request("POST", "/odds/new")
      .then()
      .statusCode(201);
}

bodyとして送信されたOddオブジェクトは自動的にJSONに変換されます。 送信するStringPOSTbodyとして渡すこともできます。

7. デフォルト値の構成

テストには多くのデフォルト値を設定できます。

@Before
public void setup() {
    RestAssured.baseURI = "https://api.github.com";
    RestAssured.port = 443;
}

ここでは、リクエストのベースURIとポートを設定しています。 これらに加えて、ベースパス、ルートpat、および認証を構成することもできます。

注:以下を使用して、RESTで保証された標準のデフォルトにリセットすることもできます。

RestAssured.reset();

8. 応答時間を測定する

Responseオブジェクトのtime()メソッドとtimeIn()メソッドを使用して応答時間を測定する方法を見てみましょう。

@Test
public void whenMeasureResponseTime_thenOK() {
    Response response = RestAssured.get("/users/eugenp");
    long timeInMS = response.time();
    long timeInS = response.timeIn(TimeUnit.SECONDS);
    
    assertEquals(timeInS, timeInMS/1000);
}

ご了承ください:

  • time()は、ミリ秒単位の応答時間を取得するために使用されます
  • timeIn()は、指定された時間単位で応答時間を取得するために使用されます

8.1. 応答時間を検証する

単純なlong Matcher:を使用して、応答時間をミリ秒単位で検証することもできます。

@Test
public void whenValidateResponseTime_thenSuccess() {
    when().get("/users/eugenp").then().time(lessThan(5000L));
}

別の時間単位で応答時間を検証する場合は、 time()マッチャーと2番目のTimeUnitパラメーターを使用します。

@Test
public void whenValidateResponseTimeInSeconds_thenSuccess(){
    when().get("/users/eugenp").then().time(lessThan(5L),TimeUnit.SECONDS);
}

9. XML応答の検証

JSON応答を検証できるだけでなく、XMLも検証できます。

http:// localhost:8080 / employees にリクエストを送信すると、次の応答が返されます。

<employees>
    <employee category="skilled">
        <first-name>Jane</first-name>
        <last-name>Daisy</last-name>
        <sex>f</sex>
    </employee>
</employees>

ファーストネームジェーンのようになっていることを確認できます。

@Test
public void givenUrl_whenXmlResponseValueTestsEqual_thenCorrect() {
    post("/employees").then().assertThat()
      .body("employees.employee.first-name", equalTo("Jane"));
}

また、次のようにボディマッチャーをチェーン化することで、すべての値が期待値と一致することを確認できます。

@Test
public void givenUrl_whenMultipleXmlValuesTestEqual_thenCorrect() {
    post("/employees").then().assertThat()
      .body("employees.employee.first-name", equalTo("Jane"))
        .body("employees.employee.last-name", equalTo("Daisy"))
          .body("employees.employee.sex", equalTo("f"));
}

または、可変引数を使用した短縮バージョンを使用します。

@Test
public void givenUrl_whenMultipleXmlValuesTestEqualInShortHand_thenCorrect() {
    post("/employees")
      .then().assertThat().body("employees.employee.first-name", 
        equalTo("Jane"),"employees.employee.last-name", 
          equalTo("Daisy"), "employees.employee.sex", 
            equalTo("f"));
}

10. XPath for XML

XPathを使用して応答を検証することもできます。でマッチャーを実行する以下の例を検討してください。

@Test
public void givenUrl_whenValidatesXmlUsingXpath_thenCorrect() {
    post("/employees").then().assertThat().
      body(hasXPath("/employees/employee/first-name", containsString("Ja")));
}

XPathは、equalToマッチャーを実行する別の方法も受け入れます。

@Test
public void givenUrl_whenValidatesXmlUsingXpath2_thenCorrect() {
    post("/employees").then().assertThat()
      .body(hasXPath("/employees/employee/first-name[text()='Jane']"));
}

11. ロギングテストの詳細

11.1. ログリクエストの詳細

まず、 log()。all():を使用してリクエストの詳細全体をログに記録する方法を見てみましょう。

@Test
public void whenLogRequest_thenOK() {
    given().log().all()
      .when().get("/users/eugenp")
      .then().statusCode(200);
}

これにより、次のようなログが記録されます。

Request method:	GET
Request URI:	https://api.github.com:443/users/eugenp
Proxy:			<none>
Request params:	<none>
Query params:	<none>
Form params:	<none>
Path params:	<none>
Multiparts:		<none>
Headers:		Accept=*/*
Cookies:		<none>
Body:			<none>

リクエストの特定の部分のみをログに記録するために、 log()メソッドを params()、body()、headers()、cookies()、method()、path( )例: log。()。params()。

使用される他のライブラリまたはフィルターは、サーバーに実際に送信されるものを変更する可能性があるため、これは最初の要求仕様をログに記録するためにのみ使用する必要があることに注意してください。

11.2. ログ応答の詳細

同様に、応答の詳細をログに記録できます。

次の例では、応答本文のみをログに記録しています。

@Test
public void whenLogResponse_thenOK() {
    when().get("/repos/eugenp/tutorials")
      .then().log().body().statusCode(200);
}

サンプル出力:

{
    "id": 9754983,
    "name": "tutorials",
    "full_name": "eugenp/tutorials",
    "private": false,
    "html_url": "https://github.com/eugenp/tutorials",
    "description": "The \"REST With Spring\" Course: ",
    "fork": false,
    "size": 72371,
    "license": {
        "key": "mit",
        "name": "MIT License",
        "spdx_id": "MIT",
        "url": "https://api.github.com/licenses/mit"
    },
...
}

11.3. 状態が発生した場合のログ応答

エラーが発生した場合、またはステータスコードが特定の値と一致した場合にのみ、応答をログに記録するオプションもあります。

@Test
public void whenLogResponseIfErrorOccurred_thenSuccess() {
 
    when().get("/users/eugenp")
      .then().log().ifError();
    when().get("/users/eugenp")
      .then().log().ifStatusCodeIsEqualTo(500);
    when().get("/users/eugenp")
      .then().log().ifStatusCodeMatches(greaterThan(200));
}

11.4. 検証に失敗した場合はログに記録する

検証が失敗した場合にのみ、要求と応答の両方をログに記録することもできます。

@Test
public void whenLogOnlyIfValidationFailed_thenSuccess() {
    when().get("/users/eugenp")
      .then().log().ifValidationFails().statusCode(200);

    given().log().ifValidationFails()
      .when().get("/users/eugenp")
      .then().statusCode(200);
}

この例では、ステータスコードが200であることを検証します。 これが失敗した場合にのみ、要求と応答がログに記録されます。

12. 結論

このチュートリアルでは、 REST保証フレームワークを調査し、RESTfulサービスをテストしてその応答を検証するために使用できる最も重要な機能を確認しました。

これらすべての例とコードスニペットの完全な実装は、RESTで保証されたGitHubプロジェクトにあります。