Teste da API REST com Karate

Teste da API REST com Karate

1. Visão geral

Neste artigo, apresentaremosKarate, uma estrutura de teste Behavior Driven Development (BDD) para Java.

2. Karate e BDD

Karate isbuilt on top of Cucumber, outra estrutura de teste do BDD e compartilha alguns dos mesmos conceitos. Um deles éthe use of a Gherkin file, which describes the tested feature. No entanto, ao contrário do Cucumber, os testes não são escritos em Java e são totalmente descritos no arquivo Gherkin.

Um arquivo Gherkin é salvo com a extensão “.feature”. Ele começa com a palavra-chaveFeature, seguida pelo nome do recurso na mesma linha. Ele também contém diferentes cenários de teste, cada um começando com a palavra-chaveScenario e consistindo em várias etapas com as palavras-chaveGiven,When,Then,And, e But.

Mais sobre o Pepino e a estrutura do Maxixe pode ser encontradohere.

3. Dependências do Maven

Para fazer uso do Karate em um projeto Maven, precisamos adicionar a dependênciakarate-apache aopom.xml:


    com.intuit.karate
    karate-apache
    0.6.0

Também precisaremos da dependênciakarate-junit4 para facilitar o teste JUnit:


    com.intuit.karate
    karate-junit4
    0.6.0

4. Criando testes

Começaremos escrevendo testes para alguns cenários comuns em um arquivo GherkinFeature.

4.1. Testando o código de status

Vamos escrever um cenário que testa um endpoint GET e verifica se ele retorna um código de status HTTP200 (OK):

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

Obviamente, isso funciona com todos os códigos de status HTTP possíveis.

4.2. Testando a Resposta

Vamos escrever outro cenário que testa se o endpoint REST retorna uma resposta específica:

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

The match operation is used for the validation onde ‘$' representa a resposta. Portanto, o cenário acima verifica se a resposta corresponde exatamente a ‘\{id:”1234″,name:”John Smith”}'.

Também podemos verificar especificamente o valor do campoid:

And match $.id == "1234"

The match operation can also be used to check if the response contains certain fields. Isso é útil quando apenas alguns campos precisam ser verificados ou quando nem todos os campos de resposta são conhecidos:

Scenario: Testing that GET response contains specific field
Given url 'http://localhost:8080/user/get'
When method GET
Then status 200
And match $ contains {id:"1234"}

4.3. Validando Valores de Resposta com Marcadores

No caso em que não sabemos o valor exato que é retornado, ainda podemos validar o valor usandomarkers - marcadores para campos correspondentes na resposta.

Por exemplo, podemos usar um marcador para indicar se esperamos um valornull ou não:

  • #null

  • #notnull

Ou podemos usar um marcador para corresponder a um determinado tipo de valor em um campo:

  • #boolean

  • #number

  • #string

Outros marcadores estão disponíveis para quando esperamos que um campo contenha um objeto ou matriz JSON:

  • #array

  • #object

E há marcadores para correspondência em um determinado formato ou expressão regular e um que avalia uma expressão booleana:

  • O valor#uuid — está em conformidade com o formato UUID

  • O valor de#regex STR — corresponde à expressão regularSTR

  • #? EXPR — afirma que a expressão JavaScriptEXPR avalia paratrue

Finalmente, se não quisermos nenhum tipo de verificação em um campo, podemos usar o marcador#ignore.

Vamos reescrever o cenário acima para verificar se o campoid não énull:

Scenario: Test GET request exact response
Given url 'http://localhost:8080/user/get'
When method GET
Then status 200
And match $ == {id:"#notnull",name:"John Smith"}

4.4. Testando um Endpoint POST com um corpo de solicitação

Vejamos um cenário final que testa um endpoint POST e leva um corpo de solicitação:

Scenario: Testing a POST endpoint with request body
Given url 'http://localhost:8080/user/create'
And request { id: '1234' , name: 'John Smith'}
When method POST
Then status 200
And match $ contains {id:"#notnull"}

5. Executando testes

Agora que os cenários de teste estão completos, podemos executar nossos testes integrando o Karate ao JUnit.

Usaremos a anotação@CucumberOptions para especificar a localização exata dos arquivosFeature:

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

Para demonstrar a API REST, usaremos umWireMock server.

Para este exemplo, simulamos todos os terminais que estão sendo testados no método anotado com@BeforeClass. Desligaremos o servidor WireMock no método anotado com@AfterClass:

private static WireMockServer wireMockServer
  = new WireMockServer();

@BeforeClass
public static void setUp() throws Exception {
    wireMockServer.start();
    configureFor("localhost", 8080);
    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();
}

Quando executamos a classeKarateUnitTest, os Endpoints REST são criados pelo WireMock Server e todos os cenários no arquivo de recurso especificado são executados.

6. Conclusão

Neste tutorial, vimos como testar APIs REST usando o Karate Testing Framework.

O código-fonte completo e todos os trechos de código para este artigo podem ser encontradosover on GitHub.