Ein Leitfaden für REST-gesichert

Ein Leitfaden für REST-versicherte

1. Einführung

REST-assured wurde entwickelt, um das Testen und Validieren von REST-APIs zu vereinfachen, und wird in hohem Maße von Testtechniken beeinflusst, die in dynamischen Sprachen wie Ruby und Groovy verwendet werden.

Die Bibliothek bietet eine solide Unterstützung für HTTP, beginnend mit den Verben und Standard-HTTP-Operationen, geht aber auch weit über diese Grundlagen hinaus.

In diesem Handbuch gehen wir zuexplore REST-assured und verwenden Hamcrest, um die Behauptung aufzustellen. Wenn Sie mit Hamcrest noch nicht vertraut sind, sollten Sie zuerst das Tutorial auffrischen:Testing with Hamcrest.

Weitere Informationen zu fortgeschrittenen Anwendungsfällen von REST-Assured finden Sie in den folgenden Artikeln:

Lassen Sie uns nun mit einem einfachen Beispiel eintauchen.

2. Einfacher Beispieltest

Bevor wir beginnen, stellen wir sicher, dass unsere Tests die folgenden statischen Importe haben:

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

Wir benötigen dies, um die Tests einfach zu halten und einfachen Zugriff auf die Haupt-APIs zu haben.

Beginnen wir nun mit dem einfachen Beispiel - einem grundlegenden Wettsystem, das einige Daten für Spiele bereitstellt:

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

Angenommen, dies ist die JSON-Antwort beim Aufrufen der lokal bereitgestellten API -http://localhost:8080/events?id=390.:

Verwenden wir jetzt REST-versichert, um einige interessante Funktionen der Antwort JSON zu überprüfen:

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

Was wir hier getan haben, ist - wir haben überprüft, dass ein Aufruf des Endpunkts/events?id=390 mit einem Körper antwortet, derJSON String enthält, dessenleagueId desdata-Objekts 35 ist.

Schauen wir uns ein interessanteres Beispiel an. Angenommen, Sie möchten überprüfen, ob das Arrayodds Datensätze mit den Preisen1.30 und5.25 enthält:

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

3. REST-sicheres Setup

Wenn Ihr bevorzugtes Abhängigkeitstool Maven ist, fügen wir der Dateipom.xmldie folgende Abhängigkeit hinzu:


    io.rest-assured
    rest-assured
    3.0.0
    test

Folgen Siethis link, um die neueste Version zu erhalten. REST-versichert nutzt die Macht der Hamcrest-Matcher, um seine Behauptungen zu erfüllen. Daher müssen wir auch diese Abhängigkeit berücksichtigen:


    org.hamcrest
    hamcrest-all
    1.3

Die neueste Version ist immer beithis link verfügbar.

4. Anonyme JSON-Stammvalidierung

Betrachten Sie ein Array, das eher aus Grundelementen als aus Objekten besteht:

[1, 2, 3]

Dies wird als anonymer JSON-Stamm bezeichnet. Dies bedeutet, dass er kein Schlüssel-Wert-Paar hat, jedoch immer noch gültige JSON-Daten sind.

In einem solchen Szenario können wir die Validierung ausführen, indem wir das`$`-Symbol oder einen leeren String ("") als Pfad verwenden. Angenommen, wir legen den oben genannten Service durchhttp://localhost:8080/json offen, dann können wir ihn mit REST-versichert wie folgt validieren:

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

oder so:

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

5. Schwimmt und verdoppelt

Wenn wir REST-Assured zum Testen unserer REST-Services verwenden, müssen wir verstehen, dass Gleitkommazahlen in JSON-Antworten dem primitiven Typfloat. zugeordnet sind

Die Verwendung des Typsfloat ist nicht mitdouble austauschbar, wie dies bei vielen Szenarien in Java der Fall ist.

Ein typisches Beispiel ist diese Antwort:

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

Angenommen, wir führen den folgenden Test für den Wert vonck durch:

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

Dieser Test schlägt auch dann fehl, wenn der Wert, den wir testen, dem Wert in der Antwort entspricht. Dies liegt daran, dass wir eher mitdouble als mitfloat vergleichen.

Damit es funktioniert, müssen wir den Operanden für die Matcher-MethodeequalToexplizit alsfloat angeben, wie folgt:

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

6. Angeben der Anforderungsmethode

Normalerweise führen wir eine Anforderung durch, indem wir eine Methode wieget(), aufrufen, die der Anforderungsmethode entspricht, die wir verwenden möchten.

Zusätzlichwe can also specify the HTTP verb using the request() method:

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

Das obige Beispiel entspricht der direkten Verwendung vonget().

Ebenso können wirHEAD,CONNECT undOPTIONS Anfragen senden:

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

Die Anforderung vonPOSTfolgt ebenfalls einer ähnlichen Syntax, und wir könnenthe body by mit den Methodenwith() andbody()angeben.

So erstellen Sie ein neuesOdd  durch Senden einerPOST -Anforderung:

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

Das alsbody will gesendeteOdd -Objekt wird automatisch in JSON konvertiert. Wir können auch alleString, die wir senden möchten, alsPOSTbody. übergeben

7. Konfiguration der Standardwerte

Wir können viele Standardwerte für die Tests konfigurieren:

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

Hier legen wir einen Basis-URI und einen Port für unsere Anforderungen fest. Daneben können wir auch den Basispfad, das Root-Pat und die Authentifizierung konfigurieren.

Hinweis: Wir können auch die Standardeinstellungen mit REST-Garantie wiederherstellen, indem wir Folgendes verwenden:

RestAssured.reset();

8. Reaktionszeit messen

Mal sehen, wie wirmeasure the response time using the time() and timeIn() methods of the Response object können:

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

Beachten Sie, dass:

  • time() wird verwendet, um die Antwortzeit in Millisekunden zu erhalten

  • timeIn() wird verwendet, um die Antwortzeit in der angegebenen Zeiteinheit abzurufen

8.1. Antwortzeit validieren

Wir können die Antwortzeit - in Millisekunden - auch mit Hilfe von einfachenlongMatcher: validieren

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

Wenn wir die Antwortzeit in einer anderen Zeiteinheit validieren möchten, verwenden wir dentime()-Matcher mit einem zweitenTimeUnit-Parameter:

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

9. Überprüfung der XML-Antwort

Es kann nicht nur eine JSON-Antwort validieren, sondern auch XML.

Nehmen wir an, wir stellen eine Anfrage anhttp://localhost:8080/employees und erhalten die folgende Antwort:


    
        Jane
        Daisy
        f
    

Wir können überprüfen, obfirst-nameJane wie folgt ist:

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

Wir können auch überprüfen, ob alle Werte mit unseren erwarteten Werten übereinstimmen, indem wir Body Matcher wie folgt miteinander verketten:

@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"));
}

Oder verwenden Sie die Kurzfassung mit variablen Argumenten:

@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 für XML

We can also verify our responses using XPath. Betrachten Sie das folgende Beispiel, in dem ein Matcher fürfirst-name ausgeführt wird:

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

XPath akzeptiert auch eine alternative Methode zum Ausführen des Matchers vonequalTo:

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

11. Details zum Protokollierungstest

11.1. Details zur Protokollanforderung

Lassen Sie uns zunächst sehen, wielog entire request details using*log().all()*:

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

Dies wird so etwas protokollieren:

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

Um nur bestimmte Teile der Anfrage zu protokollieren, haben wir dielog()-Methode in Kombination mitparams(), body(), headers(), cookies(), method(), path(), z. B.log.().params().

Beachten Sie, dass andere verwendete Bibliotheken oder Filter möglicherweise ändern, was tatsächlich an den Server gesendet wird. Daher sollte dies nur zum Protokollieren der anfänglichen Anforderungsspezifikation verwendet werden.

11.2. Details zur Protokollantwort

Ebenso können wir die Antwortdetails protokollieren.

Im folgenden Beispiel protokollieren wir nur den Antworttext:

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

Beispielausgabe:

{
    "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. Protokollantwort, wenn Bedingung aufgetreten ist

Wir haben auch die Möglichkeit, die Antwort nur dann zu protokollieren, wenn ein Fehler aufgetreten ist oder der Statuscode mit einem bestimmten Wert übereinstimmt:

@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. Protokollieren, wenn die Validierung fehlgeschlagen ist

Wir können sowohl Anforderungen als auch Antworten nur dann protokollieren, wenn unsere Validierung fehlgeschlagen ist:

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

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

In diesem Beispiel möchten wir überprüfen, ob der Statuscode 200 ist. Nur wenn dies fehlschlägt, werden die Anforderung und die Antwort protokolliert.

12. Fazit

In diesem Tutorial haben wirexplored the REST-assured framework und haben uns die wichtigsten Funktionen angesehen, mit denen wir unsere RESTful-Services testen und ihre Antworten validieren können.

Die vollständige Implementierung all dieser Beispiele und Codefragmente finden Sie in den REST-versichertenGitHub project.