REST API Testen mit Karate

1. Übersicht

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

2. Karate und BDD

Karate basiert auf Cucumber , einem anderen BDD-Testframework, und teilt einige der gleichen Konzepte. Eine davon ist die Verwendung einer Gherkin-Datei, die die getestete Funktion beschreibt . 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 Feature- Schlüsselwort, gefolgt vom Feature-Namen in derselben Zeile. Es enthält auch verschiedene Testszenarien, die jeweils mit dem Schlüsselwort Szenario beginnen und aus mehreren Schritten mit den Schlüsselwörtern Given , When , Then , And und But bestehen .

Mehr über Gurke und die Gurkenstruktur finden Sie hier.

3. Maven-Abhängigkeiten

Um Karate in einem Maven-Projekt verwenden zu können, müssen wir der pom.xml die Karate-Apache- Abhängigkeit hinzufügen :

 com.intuit.karate karate-apache 0.6.0 

Wir benötigen auch die Karate-Junit4- Abhängigkeit, um JUnit-Tests zu erleichtern:

 com.intuit.karate karate-junit4 0.6.0 

4. Tests erstellen

Zunächst schreiben wir Tests für einige gängige Szenarien in eine Gherkin- Feature- Datei.

4.1. Testen des Statuscodes

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

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

Dies funktioniert offensichtlich mit allen möglichen HTTP-Statuscodes.

4.2. Testen der Antwort

Lassen Sie uns ein weiteres Szenario schreiben, in dem getestet wird, ob der REST-Endpunkt eine bestimmte Antwort zurückgibt:

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

Die Übereinstimmungsoperation wird für die Validierung verwendet, 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 ID- Felds suchen :

And match $.id == "1234"

Die Übereinstimmungsoperation kann auch verwendet werden, um zu überprüfen, ob die Antwort bestimmte Felder enthält. 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 '//localhost:8097/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 mithilfe von Markierungen - Platzhaltern für übereinstimmende Felder in der Antwort - validieren .

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

  • #Null
  • #nicht null

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

  • #boolean
  • #Nummer
  • #string

Andere Markierungen sind verfügbar, wenn wir erwarten, dass ein Feld ein JSON-Objekt oder -Array enthält:

  • #array
  • #Objekt

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

  • #uuid - Wert entspricht dem UUID-Format
  • #regex STR - Wert entspricht dem regulären Ausdruck STR
  • #? EXPR - behauptet, dass der JavaScript-Ausdruck EXPR als wahr ausgewertet wird

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

Schreiben wir das obige Szenario neu, um zu überprüfen, ob das ID- Feld nicht null ist :

Scenario: Test GET request exact response Given url '//localhost:8097/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 '//localhost:8097/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

Now that the test scenarios are complete, we can run our tests by integrating Karate with JUnit.

We'll use the @CucumberOptions annotation to specify the exact location of the Feature files:

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

To demonstrate the REST API, we'll use a WireMock server.

For this example, we mock all the endpoints that are being tested in the method annotated with @BeforeClass. We'll shut down the WireMock server in the method annotated with @AfterClass:

private static WireMockServer wireMockServer = new WireMockServer(WireMockConfiguration.options().port(8097)); @BeforeClass public static void setUp() throws Exception { wireMockServer.start(); configureFor("localhost", 8097); 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(); }

When we run the KarateUnitTest class, the REST Endpoints are created by the WireMock Server, and all the scenarios in the specified feature file are run.

6. Conclusion

In this tutorial, we looked at how to test REST APIs using the Karate Testing Framework.

Den vollständigen Quellcode und alle Codefragmente für diesen Artikel finden Sie auf GitHub.