REST保証のガイド

1前書き

RESTアシュアードは、REST APIのテストと検証を単純化するように設計されており、RubyやGroovyなどの動的言語で使用されるテスト手法の影響を強く受けています。

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

このガイドでは、 RESTを保証 したものを探究し、Hamcrestを使ってアサーションを行います。まだHamcrestに慣れていない場合は、まずチュートリアルを読み上げる必要があります。

また、REST保証のより高度なユースケースについて学ぶために、他の記事をチェックしてください。

Groovyで]** link:/rest-assured-json-schema[JSONスキーマの検証

安心してください]** link:/rest-assured-header-cookie-parameter[パラメータ、ヘッダ、

RESTが保証されたクッキー]

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

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

レスポンスJSONの興味深い機能を検証するために、REST保証を使用しましょう。

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

それで、ここで何をしましたか?エンドポイント /events?= id = 390 への呼び出しが、 data オブジェクトの leagueId が35の JSON String を含む本文で応答することを確認しました。

もっと面白い例を見てみましょう。 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.0.0</version>
    <scope>test</scope>
</dependency>

最新版を入手するには、https://search.maven.org/classic/#search%7Cga%7C1%7Ca%3A%22rest-assured%22[このリンク]に従ってください。 REST-assuredはHamcrest matcherの力を利用してアサーションを実行するため、その依存関係も含める必要があります。

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

最新版は常にhttps://search.maven.org/classic/#search%7Cga%7C1%7Ca%3A%22hamcrest-all%22[このリンク]から入手できます。

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アシュアードを使い始めるときには、JSON応答の浮動小数点数がプリミティブ型 float. にマップされることを理解する必要があります。

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

その好例は次のとおりです。

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

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

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

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

これを機能させるには、 equalTo matcherメソッドのオペランドを 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() メソッドを使って the body __を指定することができます。

したがって、 __ POST requestを送信して新しい Odd __を作成するには、次のようにします。

@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に変換されます。 POST body. として送信したい String__を渡すこともできます。

7. デフォルト値設定

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

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

ここでは、リクエスト用のベースURIとポートを設定します。これらの他に、ベースパス、ルートパッチ、認証も設定できます。

注:以下を使用して標準の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));
}

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

@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>

以下のように、ファーストネームが Jane であることを確認できます。

@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 matcherを実行する別の方法も受け入れます。

@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() と組み合わせて使用​​します。 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保証のhttps://github.com/eugenp/tutorials/tree/master/testing-modules/rest-assured[GitHubプロジェクト]にあります。