sábado, 4 de mayo de 2019

REST Assured y como probar tus APIs REST


Hoy vamos a ver un software que nos permita hacer las pruebas a nuestra API REST, y este es: REST Assured. Para ello utilizaremos otra vez el servicio web  que ya hicimos con Jersey.

Para empezar decir que REST Assured esta basado en dos patrones de diseños: Fluent y Behaviour-driven development. Es decir:
  • Podemos concatenar la ejecución de los métodos. 
  • Nos proporciona métodos que nos aportan mayor legibilidad (aunque a efectos practicos no tengan una mayor trascendencia).
Rest Assured tiene una múltitud de métodos que nos ayudarán facilmente y junto con Hamcrest a testear completamente una API REST. Vamos a ir viendo su funcionamiento poco a poco y a través de ejemplos, pero centrandonos sobre todo en su funcionalidad JSON y dejando de lado su funcionalidad XML que también la tiene. 
  • Testear el cuerpo de la respuesta a través de body o content. Para navegar sobre el objeto JSON nos podemos ayudar de JSONPath. En este ejemplo también podemos ver los métodos BDD: given, when o then.
@Test
public void validateBody() {
 // http://localhost:8080/JerseyExample/rest/book
 given().when().get("/JerseyExample/rest/book").then().content("id[0]", equalTo(1));
 given().when().get("/JerseyExample/rest/book").then().body("id", hasItems(1, 2, 3));
 given().when().get("/JerseyExample/rest/book/list").then().body("library.findAll { it.id < 2 }.author", hasItems("Isaac Asimov"));
}
  • Testear una sección concreta del objeto JSON, y marcarla como el centro del objeto para ayudarnos en los JSONPATH a través del método root. También vemos el uso del método BDD,  and que nos ayuda a la hora de concatenar asserts. 
get("/JerseyExample/rest/book").then().root("[0]").body("author", equalTo("Isaac Asimov")).and().body("id", equalTo(1));
  • Indicar parámetros de forma dinámica en la llamada. 
get("/JerseyExample/rest/book/{id}", 1).then().body("id", equalTo(1));
  • Validar la respuesta HTTP: cabecera, status code, cookies o content type.
get("/JerseyExample/rest/book").then().contentType("application/json");
// get("/JerseyExample/rest/book").then().cookie("JSESSIONID");
get("/JerseyExample/rest/book").then().header("Content-Type", "application/json");
get("/JerseyExample/rest/book").then().statusCode(200);
  • Validar el esquema JSON de la respuesta.
get("/JerseyExample/rest/book/1").then().assertThat().body(matchesJsonSchemaInClasspath("book-schema.json"));
  • Extraer el contenido como un conjunto de objetos y realizar asercciones posteriormente
List<Map<String, Object>> books = get("/JerseyExample/rest/book").as(new TypeRef<List<Map<String, Object>>>() {});
assertThat(books, hasSize(3));
assertThat(books.get(0).get("author"), equalTo("Isaac Asimov"));
  • Extraer el contenido o parte del contenido en un formato concreto y otros valores de la respuesta.
String json = get("/JerseyExample/rest/book/1").asString();
assertThat(json, equalTo("{\"id\":1,\"author\":\"Isaac Asimov\",\"name\":\"Foundation\"}"));
Map<String, String> allCookies = get("/JerseyExample/rest/book/1").getCookies();
assertThat(allCookies.size(), equalTo(0));
String pathValue = get("/JerseyExample/rest/book/1").path("author");
assertThat(pathValue, equalTo("Isaac Asimov"));
  • Incluir logs, de todo o solo de partes concretas. O validar el tiempo que tarda en realizarse las llamadas.
given().log().all().get("/JerseyExample/rest/book/{id}", 1).then().time(lessThan(2000L));

Como veis, se pueden hacer muchas cosas. En estos ejemplos nos hemos centrado más en la parte de validar el JSON. Y hemos dejado de lado las validaciones XML o validaciones más complejas de tipo autenticación o cross-site, que también las tiene.

No hay comentarios:

Publicar un comentario