A EclipseSource lançou a primeira versão estável de uma extensão open souce do JUnit para automação de testes de serviços REST/HTTP. O Restfuse é um conjunto de anotações para JUnit que oferece asserções para respostas de requisições HTTP. Tanto chamadas síncronas como assíncronas são suportadas.
O Restfuse já está disponível no Maven Central, então para usá-lo não é necessário nenhum repositório especial:
<dependency> <groupId>com.restfuse</groupId> <artifactId>com.eclipsesource.restfuse</artifactId> <version>1.0.0</version> </dependency>
Usar a biblioteca para chamadas síncronas é simples e direto:
@RunWith(HttpJUnitRunner.class) public class RestFuseTest { @Rule public Destination destination = new Destination("http://example.com" ); @Context private Response response; // será injetado depois de cada chamada @HttpTest(method = Method.GET, path = "/reloadLocalConfiguration" ) public void checkRestfuseOnlineStatus() { assertOk(response ); String answerBody = response.getBody(String.class); assertEquals("Expected correct response","done",answerBody); } }
O teste acima chama um endereço HTTP de maneira síncrona e então valida se há uma resposta textual (text/plain) contendo a string "done". Note que a primeira asserção, assertOk, é do Restfuse; ela verifica se o status da resposta HTTP foi 200 OK. A segunda asserção, assertEquals, verifica a igualdade como no JUnit. Embora esteja se supondo que o endereço HTTP vai retornar um texto puro, poderia também ser processado conteúdo em JSON/XML ou de outro tipo, e executar os asserts de maneira estruturada.
O Restfuse também suporta chamadas assíncronas. Uma aplicação clássica disso se dá em operações de longa duração (como o upload de um arquivo extenso), em que o cliente monitora continuamente o servidor para identificar o status atual. No exemplo abaixo, é considerado um endereço do lado servidor que retorna um número entre 0 e 100 e mostra o progresso de alguma operação:
@RunWith( HttpJUnitRunner.class ) public class PollTest1 { @Rule public Destination destination = new Destination( "http://example.com" ); @Context private Response response; @Context private PollState pollState; @HttpTest( method = Method.GET, path = "/progressStatus" ) @Poll( times = 5, interval = 500 ) public void testAsynchronousService() { if(pollState.getTimes() == 5) { String answerBody = response.getBody(String.class); assertEquals("Expected last response","100",answerBody); } } }
O teste acima chama o mesmo endereço cinco vezes (com um intervalo definido), mas somente a última chamada verifica a resposta HTTP.
Uma característica interessante da interface PollState é a manutenção das respostas anteriores. Isto permite aos asserts sejam feitos sobre o histórico das chamadas:
@RunWith( HttpJUnitRunner.class ) public class PollTest2 { @Rule public Destination destination = new Destination( "http://example.com" ); @Context private Response response; @Context private PollState pollState; @HttpTest( method = Method.GET, path = "/progressStatus" ) @Poll( times = 5, interval = 500 ) public void testAsynchronousService() { int currentRun = pollState.getTimes(); if(currentRun > 1) { String previousProgress = pollState.getResponse(currentRun - 1).getBody(String.class); String presentProgress = response.getBody(String.class); assertTrue("Expected some progress",Integer.parseInt(presentProgress) > Integer.parseInt(presentProgress)); //Just for illustration purposes } } } }
O teste acima verifica se cada resposta tem número superior à resposta anterior. O Restfuse tem uma dependência com o servidor HTTP Jetty e suporta serviços assíncronos que seguem o modelo de Web Hooks. Ao invés de enviar várias requisições ao servidor para verificar o estado de um processo, o cliente cliente faz uma chamada uma única vez e então aguarda por uma resposta iniciada pelo servidor em uma conexão diferente. Aqui está um exemplo usando Restfuse:
@RunWith( HttpJUnitRunner.class ) public class RestfuseCalbackTest { @Rule public Destination destination = new Destination( "http://example.com" ); @Context private Response response; private class TestCallbackResource extends DefaultCallbackResource { @Override public Response post( Request request ) { assertTrue("Expected a quote response", request.getBody(String.class).startsWith("quote:") ); return super.post( request ); } } @HttpTest( method = Method.GET, path = "/requestQuote" ) @Callback( port = 9090, path = "/asynchron", resource = TestCallbackResource.class, timeout = 10000 ) public void testMethod() { assertAccepted( response ); } }
Este último exemplo conecta-se ao requestQuote e monitora a porta 9090 do cliente. Durante até dez segundos, ele espera uma resposta textual, começando com "quote:"
Para mais informações sobre o Restfuse, visite a wiki do projeto e seu Javadocs. O código-fonte esta hospedado no GitHub.