Testing REST services Verificação e Validação de Software Departamento de Informática Faculdade de Ciências da Universidade de Lisboa Vasco T. Vasconcelos
Some tools • Web browser: allows only for GET operations • For the remaining verbs use, for example, • curl from the command line • a dedicated REST client (preferably one that allows to save common requests)
Specifying REST APIs • Open API (was swagger), http://swagger.io • Includes an editor and SDK generators, server and clients, for multiple platforms • Apiary, https://apiary.io • Provides for API mocking • Clients may use an API before it is implemented (no support for persistence) • Proprietary language (API blueprint), but may use Swagger specs
Swagger editor
REST-assured • https://github.com/jayway/rest-assured • Testing REST APIs in Java • Fluent interface: • In software engineering, a fluent interface (as first coined by Eric Evans and Martin Fowler) is an implementation of an object oriented API that aims to provide more readable code (https:// en.wikipedia.org/wiki/Fluent_interface)
Getting started import static com.jayway.restassured.RestAssured.get; Path Verb @Test public void testWelcomeStatusCode() { get(“http://localhost:8080/v1/lotto"). then(). Note the indentation statusCode(200); } Success (better: In the Response use a constant) header
Better import static com.jayway.restassured.RestAssured.baseURI; @BeforeClass public static void testSetup() { baseURI = "http://localhost:8080/lotto"; // Setup the database } Implicit path @Test public void testWelcomeStatusCode() { get(). then(). statusCode(200); }
Analysing responses • Assume that GET returns the following JSON { "lotto":{ "lottoId":5, "winning-numbers":[2,45,34,23,7,5,3], "winners":[{ "winnerId":23, "numbers":[2,45,34,23,3,5] },{ "winnerId":54, "numbers":[52,3,12,11,18,22] }] } }
Paths in JSON import static org.hamcrest.Matchers.equalTo; @Test public void testLottoIdIs5() { get().then().body("lotto.lottoId", equalTo(5));; } A path in An hamcrest JSON Matcher
More paths import static org.hamcrest.Matchers.hasItems; @Test public void testLottoHasItems() { get(). then(). body(“lotto.winners.winnerId", hasItems(23, 54)); } Another hamcrest Matcher
Java Hamcrest • “Matchers that can be combined to create flexible expressions of intent” • Check the various matchers available at http:// hamcrest.org/JavaHamcrest/javadoc/1.3/org/ hamcrest/Matchers.html
Preparing JSON with a Map @Test public void testPOSTPet() { Map<String, Object> pet = new HashMap<>(); pet.put("id", 32); pet.put("name", "Felix"); pet.put("status", “alive"); given(). contentType("application/json"). Specify the body(pet). content type when(). JSON with 3 post(). properties then(). statusCode(201); Created }
Preparing JSON with a Builder import javax.json.Json; @Test public void testPOSTPetBuilder() { String pet = Json.createObjectBuilder(). add("id", 32). add("name", "Felix"). add("status", "alive"). build().toString(); given(). contentType("application/json"). body(pet). when(). post(). then(). statusCode(201); }
Saving responses for later use • Suppose that a POST returns the following header HTTP 201 Created Location: http://localhost:8080/v1/258 Content-Type: text/html Date: Mon, 16 May 2016 11:09:28 GMT Content-Length: 74 X-Powered-By: Undertow/1 Connection: keep-alive Server: WildFly/10 • and that one whats to recall the location for further use
Saving responses @Test public void testGet() { String pet = Json.createObjectBuilder()…; String location = given(). contentType("application/json"). body(pet). when(). post(). Created Extract the string then(). under property Location statusCode(201). extract().header("Location"); Extract Now check that the from the pet was properly get(location).then().statusCode(200); header POSTed }
Recommend
More recommend