O desenvolvimento de aplicativos Web tem evoluído rapidamente nos últimos anos, e a criação de APIs RESTful tornou-se uma prática comum para construir sistemas escaláveis e interoperáveis. Neste tutorial vamos criar com projeto Rest Assured com Spring Boot para automatizar testes de forma simples.
O REST Assured, por sua vez, é uma biblioteca Java usada para escrever testes automatizados para APIs RESTful. Neste tutorial simples vamos integrar o esta biblioteca em um aplicativo Spring Boot para testar e validar serviços de uma api.
O que é REST Assured?
O REST Assured é uma biblioteca de teste de APIs RESTful que fornece uma sintaxe simples e intuitiva para escrever testes automatizados.
Ele simplifica o processo de criação de testes, permitindo que os desenvolvedores validem o comportamento das APIs, verifiquem as respostas HTTP, testem o conteúdo retornado e realizem asserções de maneira fácil e legível.
O Rest Assured utiliza uma sintaxe baseada em Behavior Driven Development (BDD), que torna os testes mais legíveis para os desenvolvedores. Isso é alcançado usando métodos encadeados, como given(), when(), then(), e métodos de asserção, como statusCode(), body(), header().
Integrando REST Assured com Spring Boot
Para integrar o REST Assured em um projeto Spring Boot, é necessário adicionar a dependência do REST Assured no arquivo pom.xml. Por exemplo:
<dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <version>4.4.0</version> <scope>test</scope> </dependency>
Agora vamos criar uma classe de teste que vai testar 5 requisições Http em uma api com Spring Boot.
Cada um dos testes são testados de forma isolada, como temos 5 métodos diferentes em nossa api, cada um precisa ter um exclusivo, claro que existe muitos outros cenários de testes que poderíamos realizar, porém o artigo ficaria muito grande e resolvi utilizar apenas estes 5:
package br.com.virandoprogramador.test.restassured import static io.restassured.RestAssured.*; import static org.hamcrest.Matchers.*; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class RestAssuredAPITests { @LocalServerPort private int port; private static String BASE_URL; @BeforeAll public static void setup() { BASE_URL = "http://localhost:8080"; } @Test public void testGetEndpoint() { given() .when() .get(BASE_URL + "/api/endpoint") .then() .statusCode(200); } @Test public void testPostEndpoint() { given() .contentType("application/json") .body("{\"key\":\"value\"}") .when() .post(BASE_URL + "/api/endpoint") .then() .statusCode(201); } @Test public void testPutEndpoint() { given() .contentType("application/json") .body("{\"key\":\"updatedValue\"}") .when() .put(BASE_URL + "/api/endpoint/1") .then() .statusCode(200); } @Test public void testDeleteEndpoint() { given() .when() .delete(BASE_URL + "/api/endpoint/1") .then() .statusCode(204); } @Test public void testPagination() { given() .param("page", 2) .param("size", 10) .when() .get(BASE_URL + "/api/paginatedEndpoint") .then() .statusCode(200) .body("items.size()", equalTo(10)); } }
Esta classe contém diferentes testes, incluindo solicitações GET, POST, PUT e DELETE para endpoints variados, bem como um teste de paginação.
Cada método de teste na classe representa um caso de teste diferente. Eles são responsáveis por enviar solicitações HTTP para diferentes endpoints e verificar as respostas recebidas.
Detalhando cada Teste da classe RestAssuredAPITests
Para fixar ainda mais o entendimento, vou tentar explicar com mais detalhes o que cada teste está fazendo, cada um deles tem uma definição única, veja mais:
1. testGetEndpoint()
@Test public void testGetEndpoint() { given() .when() .get(BASE_URL + "/api/endpoint") .then() .statusCode(200); }
Este teste verifica se é possível acessar um endpoint específico através de uma requisição GET (when().get()) e se o código de status retornado é 200 (then().statusCode(200)). Basicamente, ele testa se o endpoint /api/endpoint está disponível e responde com sucesso.
Em geral os testes realizados com o método GET são um pouco mais fáceis de compreender.
2. testPostEndpoint()
@Test public void testPostEndpoint() { given() .contentType("application/json") .body("{\"key\":\"value\"}") .when() .post(BASE_URL + "/api/endpoint") .then() .statusCode(201); }
Esse teste verifica se é possível criar um novo recurso enviando uma requisição POST when().post() para o endpoint /api/endpoint com um corpo JSON contendo a chave “key” e o valor “value”.
Ele valida se a resposta retorna um código de status 201 (Created), indicando que o recurso foi criado com sucesso.
3. testPutEndpoint()
@Test public void testPutEndpoint() { given() .contentType("application/json") .body("{\"key\":\"updatedValue\"}") .when() .put(BASE_URL + "/api/endpoint/1") .then() .statusCode(200); }
Este teste verifica se é possível atualizar um recurso existente fazendo uma requisição PUT when().put() para o endpoint /api/endpoint/1 (supondo que este seja o endpoint para atualizar um recurso específico com ID 1).
Ele envia um corpo JSON com a chave “key” atualizada para updatedValue e valida se a resposta retorna um código de status 200 (OK), indicando que a atualização foi bem-sucedida.
4. testDeleteEndpoint()
@Test public void testDeleteEndpoint() { given() .when() .delete(BASE_URL + "/api/endpoint/1") .then() .statusCode(204); }
Esse teste verifica se é possível excluir um recurso existente por meio de uma requisição DELETE when().delete() para o endpoint /api/endpoint/1 (supondo que este seja o endpoint para excluir um recurso com ID 1).
Ele valida se a resposta retorna um código de status 204 (No Content), indicando que o recurso foi removido com sucesso.
5. testPagination()
@Test public void testPagination() { given() .param("page", 2) .param("size", 10) .when() .get(BASE_URL + "/api/paginatedEndpoint") .then() .statusCode(200) .body("items.size()", equalTo(10)); }
Este teste verifica se a paginação está funcionando corretamente ao acessar a segunda página de um endpoint paginado /api/paginatedEndpoint com uma solicitação GET.
Ele define parâmetros de consulta page e size para buscar a segunda página com 10 itens. Valida se a resposta retorna um código de status 200 (OK) e se o corpo da resposta contém exatamente 10 itens na lista de items.
Encerrando sobre o assunto
Através de uma sintaxe baseada em Behavior Driven Development (BDD) e sua integração direta com frameworks de teste como JUnit – Artigo Completo e TestNG, o Rest Assured simplifica significativamente a criação e a execução de testes de API.
Isso permite que os desenvolvedores escrevam casos de teste de forma clara e compreensível, o que facilita a manutenção e a identificação rápida de possíveis problemas.
Contudo, a capacidade do Rest Assured de validar uma variedade de aspectos das solicitações e respostas HTTP, juntamente com sua flexibilidade para lidar com diferentes formatos de dados e funcionalidades avançadas, como operações assíncronas e autenticação, o tornam uma escolha inteligente para cenários de teste complexos.
Ao automatizar os testes de API com o Rest Assured, as equipes de desenvolvimento podem ganhar em eficiência, detectando erros mais cedo no ciclo de desenvolvimento, promovendo a entrega de software de maior qualidade e reduzindo os custos associados à correção de problemas encontrados tardiamente.