REST-API-Test mit Karate

REST API Testen mit Karate

1. Überblick

In diesem Artikel stellen wirKarate vor, ein BDD-Testframework (Behavior Driven Development) für Java.

2. Karate und BDD

Karate isbuilt on top of Cucumber, ein weiteres BDD-Testframework, und teilt einige der gleichen Konzepte. Eine davon istthe use of a Gherkin file, which describes the tested feature. Im Gegensatz zu Cucumber sind Tests jedoch nicht in Java geschrieben und werden in der Gherkin-Datei vollständig beschrieben.

Eine Gurkendatei wird mit der Erweiterung „.feature”“ gespeichert. Es beginnt mit dem SchlüsselwortFeature, gefolgt vom Feature-Namen in derselben Zeile. Es enthält auch verschiedene Testszenarien, die jeweils mit dem SchlüsselwortScenario beginnen und aus mehreren Schritten mit den SchlüsselwörternGiven,When,Then,And und bestehen But.

Mehr über Gurke und die Gurkenstruktur finden Sie inhere.

3. Maven-Abhängigkeiten

Um Karate in einem Maven-Projekt verwenden zu können, müssen wir die Abhängigkeit vonkarate-apachezupom.xmlhinzufügen:


    com.intuit.karate
    karate-apache
    0.6.0

Wir benötigen auch die Abhängigkeit vonkarate-junit4, um das Testen von JUnit zu erleichtern:


    com.intuit.karate
    karate-junit4
    0.6.0

4. Tests erstellen

Wir beginnen damit, Tests für einige gängige Szenarien in eine GherkinFeature-Datei zu schreiben.

4.1. Testen des Statuscodes

Schreiben wir ein Szenario, in dem ein GET-Endpunkt getestet und geprüft wird, ob er einen HTTP-Statuscode von200 (OK) zurückgibt:

Scenario: Testing valid GET endpoint
Given url 'http://localhost:8080/user/get'
When method GET
Then status 200

Dies funktioniert natürlich mit allen möglichen HTTP-Statuscodes.

4.2. Testen der Antwort

Schreiben wir ein weiteres Szenario, in dem getestet wird, ob der REST-Endpunkt eine bestimmte Antwort zurückgibt:

Scenario: Testing the exact response of a GET endpoint
Given url 'http://localhost:8080/user/get'
When method GET
Then status 200
And match $ == {id:"1234",name:"John Smith"}

The match operation is used for the validation wobei „$' die Antwort darstellt. Das obige Szenario überprüft also, ob die Antwort genau mit\{id:”1234″,name:”John Smith”}'. übereinstimmt

Wir können auch speziell nach dem Wert des Feldsiduchen:

And match $.id == "1234"

The match operation can also be used to check if the response contains certain fields. Dies ist hilfreich, wenn nur bestimmte Felder überprüft werden müssen oder wenn nicht alle Antwortfelder bekannt sind:

Scenario: Testing that GET response contains specific field
Given url 'http://localhost:8080/user/get'
When method GET
Then status 200
And match $ contains {id:"1234"}

4.3. Überprüfen der Antwortwerte mit Markern

Falls wir den genauen zurückgegebenen Wert nicht kennen, können wir den Wert dennoch mitmarkers - Platzhaltern für übereinstimmende Felder in der Antwort überprüfen.

Zum Beispiel können wir einen Marker verwenden, um anzuzeigen, ob wir einennull-Wert erwarten oder nicht:

  • #null

  • #notnull

Oder wir können einen Marker verwenden, um einem bestimmten Werttyp in einem Feld zu entsprechen:

  • #boolean

  • #number

  • #string

Andere Marker sind verfügbar, wenn erwartet wird, dass ein Feld ein JSON-Objekt oder -Array enthält:

  • #array

  • #object

Und es gibt Markierungen für die Übereinstimmung mit einem bestimmten Format oder regulären Ausdruck und eine, die einen booleschen Ausdruck auswertet:

  • Der Wert von#uuid —entspricht dem UUID-Format

  • Der Wert von#regex STR —entspricht dem regulären AusdruckSTR

  • #? EXPR — behauptet, dass der JavaScript-AusdruckEXPRtrue ergibt

Wenn wir kein Feld überprüfen möchten, können wir den Marker#ignoreverwenden.

Schreiben wir das obige Szenario neu, um zu überprüfen, ob das Feldid nichtnull ist:

Scenario: Test GET request exact response
Given url 'http://localhost:8080/user/get'
When method GET
Then status 200
And match $ == {id:"#notnull",name:"John Smith"}

4.4. Testen eines POST-Endpunkts mit einem Anforderungshauptteil

Schauen wir uns ein letztes Szenario an, in dem ein POST-Endpunkt getestet und ein Anforderungshauptteil verwendet wird:

Scenario: Testing a POST endpoint with request body
Given url 'http://localhost:8080/user/create'
And request { id: '1234' , name: 'John Smith'}
When method POST
Then status 200
And match $ contains {id:"#notnull"}

5. Ausführen von Tests

Nachdem die Testszenarien abgeschlossen sind, können wir unsere Tests ausführen, indem wir Karate in JUnit integrieren.

Wir verwenden die Annotation@CucumberOptions, um den genauen Speicherort der DateienFeatureanzugeben:

@RunWith(Karate.class)
@CucumberOptions(features = "classpath:karate")
public class KarateUnitTest {
//...
}

Zur Demonstration der REST-API verwenden wirWireMock server.

In diesem Beispiel verspotten wir alle Endpunkte, die in der mit@BeforeClass versehenen Methode getestet werden. Wir werden den WireMock-Server in der mit@AfterClass angegebenen Methode herunterfahren:

private static WireMockServer wireMockServer
  = new WireMockServer();

@BeforeClass
public static void setUp() throws Exception {
    wireMockServer.start();
    configureFor("localhost", 8080);
    stubFor(
      get(urlEqualTo("/user/get"))
        .willReturn(aResponse()
          .withStatus(200)
          .withHeader("Content-Type", "application/json")
          .withBody("{ \"id\": \"1234\", name: \"John Smith\" }")));

    stubFor(
      post(urlEqualTo("/user/create"))
        .withHeader("content-type", equalTo("application/json"))
        .withRequestBody(containing("id"))
        .willReturn(aResponse()
          .withStatus(200)
          .withHeader("Content-Type", "application/json")
          .withBody("{ \"id\": \"1234\", name: \"John Smith\" }")));

}

@AfterClass
public static void tearDown() throws Exception {
    wireMockServer.stop();
}

Wenn wir die KlasseKarateUnitTestausführen, werden die REST-Endpunkte vom WireMock-Server erstellt und alle Szenarien in der angegebenen Feature-Datei ausgeführt.

6. Fazit

In diesem Tutorial haben wir uns angesehen, wie REST-APIs mit dem Karate Testing Framework getestet werden.

Der vollständige Quellcode und alle Codefragmente für diesen Artikel finden Sie unterover on GitHub.