DÊ A MÁXIMA COBERTURA NOS
SEUS TESTES DE API
ELIAS NOGUEIRA
@eliasnogueira
Conceituação
FRONTENDBACKEND
API Gateway
testes funcionais e de
aceitação para o frontend
web e/ou mobile
testes unitários e
integração no backend
testes na api de
consumo
SUT – System Under Test | Front-end
Informar um CPF:
• válido
• que não esteja com restrição
• não cadastrado
SUT – System Under Test | Front-end
Efetuar o cadastro
respeitando as restrições
SUT – System Under Test | Front-end
Efetuar operações de CRUD
Passos...
1 Entender a documentação da API
2 Pensar nos testes com uma divisão de pipeline
3 Criar uma versão inicial da arquitetura
4 Criar os testes e definir as suítes de testes
1.
Entender a
documentação da API
Open API
Swagger
Ter a documentação correta e
dentro de padrões é a melhor
forma de entender a API e iniciar
os testes .
2.
Pensar nos testes com
uma divisão de
pipeline
API
Pipeline
Health Check
Contrato
Funcional
Aceitação
Garantir que o endpoint está respondendo
Garantir que o endpoint não teve seus
atributos alterados
Garantir que o endpoint funciona ou apresenta
os resultados de falha esperados
Garantir que um conjunto de endpoints
funcionam como na UI
3.
Criar uma versão
inicial da arquitetura
Modelo 1
Um projeto de teste para cada microserviço +
um projeto de testes de aceitação
Como serão os projetos de teste?
BACKEND
TEST TEST TEST
PROEJTO
TESTE
TEST
PROJETO
ACEITAÇÃO
Modelo 2
Projeto único para todas as APIs
Como serão os projetos de teste?
BACKEND
TEST
PROEJTO
TESTE
Base Test
Ponto centralizado para pré e pós condições de teste
Builder
Criação de métodos fluentes
Data Factory
Criação de dados de forma dinâmica e centralizada
Data Driven
Estratégia de utilização de dados nos testes
Uso de Padrões de Projeto
4.
Criar testes e definir as
suítes de teste
Rest-Assured
http://rest-assured.io
DSL Java para testar e validar APIs REST.
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class ExemploRestAssured {
@Test
public void boasVindas() {
given().
param("nome", "Elias").
when().
post("/cadastro").
then().
body("mensagem", is("Olá Elias"));
}
}
Rest-Assured
http://rest-assured.io
DSL Java para testar e validar APIs REST.
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class ExemploRestAssured {
@Test
public void boasVindas() {
given().
param("nome", "Elias").
when().
post("/cadastro").
then().
body("mensagem", is("Olá Elias"));
}
}
importação das
bibliotecas necessárias
Rest-Assured
http://rest-assured.io
DSL Java para testar e validar APIs REST.
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class ExemploRestAssured {
@Test
public void boasVindas() {
given().
param("nome", "Elias").
when().
post("/cadastro").
then().
body("mensagem", is("Olá Elias"));
}
}
pré-condição para a
requisição
Rest-Assured
http://rest-assured.io
DSL Java para testar e validar APIs REST.
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class ExemploRestAssured {
@Test
public void boasVindas() {
given().
param("nome", "Elias").
when().
post("/cadastro").
then().
body("mensagem", is("Olá Elias"));
}
}
ação (requisição)
Rest-Assured
http://rest-assured.io
DSL Java para testar e validar APIs REST.
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class ExemploRestAssured {
@Test
public void boasVindas() {
given().
param("nome", "Elias").
when().
post("/cadastro").
then().
body("mensagem", is("Olá Elias"));
}
}
validação dos dados
de retorno
API
health-check
Health Check
Contrato
Funcional
Aceitação
Garantir que o endpoint está respondendo
Garantir que o endpoint não teve seus
atributos alterados
Garantir que o endpoint funciona ou apresenta
os resultados de falha esperados
Garantir que um conjunto de endpoints
funcionam como na UI
heath-check
Apenas validamos se a API está disponível
Se existir alguma abordagem de verificação ou monitoramento validamos
o status geral do retorno
@Test(groups = "health")
public void healthCheckViaActuator() {
basePath = "/actuator";
when().
get("/health").
then().
statusCode(200).
body("status", is("UP"));
}
@Test(groups = "health")
public void healthCheckViaAPI() {
given().
pathParam("cpf", "81016654049").
when().
get("/restricoes/{cpf}").
then().
statusCode(204);
}
via monitoramento via API
API
contrato
Health Check
Contrato
Funcional
Aceitação
Garantir que o endpoint está respondendo
Garantir que o endpoint não teve seus
atributos alterados
Garantir que o endpoint funciona ou apresenta
os resultados de falha esperados
Garantir que um conjunto de endpoints
funcionam como na UI
● É o nome dado ao pacto entre o produtor e consumidor
● Garante que mudanças na API não invalidem o consumo:
● path
● parâmetros
● dados de envio (request)
● dados de retorno (response body)
● json-schema é um contrato que define os dados
esperados, tipos e formatos de cada campo na resposta
contrato
{
"nome": "Elias",
"idade": 36
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"nome": {
"type": "string"
},
"idade": {
"type": "integer"
}
},
"required": [
"nome",
"idade"
],
"additionalProperties": false
}
json-schema
{
"nome": "Elias",
"idade": 36
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"nome": {
"type": "string"
},
"idade": {
"type": "integer"
}
},
"required": [
"nome",
"idade"
],
"additionalProperties": false
}
json-schema possui o nome
do atributo e o tipo de dados
json-schema
{
"nome": "Elias",
"idade": 36
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"nome": {
"type": "string"
},
"idade": {
"type": "integer"
}
},
"required": [
"nome",
"idade"
],
"additionalProperties": false
}
os dois atributos devem estar
presentes, obrigatoriamente
json-schema
{
"nome": "Elias",
"idade": 36
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"nome": {
"type": "string"
},
"idade": {
"type": "integer"
}
},
"required": [
"nome",
"idade"
],
"additionalProperties": false
}
json-schema
nenhum outro
atributo é permitido
API
funcional
Health Check
Contrato
Funcional
Aceitação
Garantir que o endpoint está respondendo
Garantir que o endpoint não teve seus
atributos alterados
Garantir que o endpoint funciona ou apresenta
os resultados de falha esperados
Garantir que um conjunto de endpoints
funcionam como na UI
funcional
Validar cenários positivos e negativos (caminho feliz | fluxo exceção)
@Test(groups = {"funcional"})
public void cPFExistente() {
given().
pathParam("cpf", "66414919004").
when().
get("/simulacoes/{cpf}").
then().
statusCode(200).
body(
"id", equalTo(1),
"nome", equalTo("Fulano"),
"cpf", equalTo("66414919004"),
"email", equalTo("fulano@gmail.com"),
"valor", equalTo(11000f),
"parcelas", equalTo(3),
"seguro", equalTo(true)
);
}
validação de dados
API
aceitação
Health Check
Contrato
Funcional
Aceitação
Garantir que o endpoint está respondendo
Garantir que o endpoint não teve seus
atributos alterados
Garantir que o endpoint funciona ou apresenta
os resultados de falha esperados
Garantir que um conjunto de endpoints
funcionam como na UI
Testar com a perspectiva do usuário
● Acessar a página e efetuar a consulta de
restrição no CPF
● Inserir uma simulação de crédito
aceitação
@Test(groups = {"aceitacao"})
public void realizaSimulacaoCredito() {
baseURI = "http://localhost";
port = 8088;
basePath = "/api/v1";
String cpf = "12345678901";
// efetua a verificacao de cpf restrito
given().
pathParam("cpf", cpf).
when().
get("/restricoes/{cpf}").
then().
statusCode(204);
// efetua a simulacao
port = 8089;
Simulacao simulacao = SimulacaoDataFactory.criaNovaSimulacao();
given().
contentType(ContentType.JSON).
body(simulacao).
when().
post("/simulacoes").
then().
statusCode(201);
}
aceitação
@Test(groups = {"aceitacao"})
public void realizaSimulacaoCredito() {
baseURI = "http://localhost";
port = 8088;
basePath = "/api/v1";
String cpf = "12345678901";
// efetua a verificacao de cpf restrito
given().
pathParam("cpf", cpf).
when().
get("/restricoes/{cpf}").
then().
statusCode(204);
// efetua a simulacao
port = 8089;
Simulacao simulacao = SimulacaoDataFactory.criaNovaSimulacao();
given().
contentType(ContentType.JSON).
body(simulacao).
when().
post("/simulacoes").
then().
statusCode(201);
}
requisição de consulta
restrição
aceitação
@Test(groups = {"aceitacao"})
public void realizaSimulacaoCredito() {
baseURI = "http://localhost";
port = 8088;
basePath = "/api/v1";
String cpf = "12345678901";
// efetua a verificacao de cpf restrito
given().
pathParam("cpf", cpf).
when().
get("/restricoes/{cpf}").
then().
statusCode(204);
// efetua a simulacao
port = 8089;
Simulacao simulacao = SimulacaoDataFactory.criaNovaSimulacao();
given().
contentType(ContentType.JSON).
body(simulacao).
when().
post("/simulacoes").
then().
statusCode(201);
}
requisição de
simulação de crédito
Obrigado!
@eliasnogueira
github.com/eliasnogueira

De a máxima cobertura nos seus testes de API

  • 1.
    DÊ A MÁXIMACOBERTURA NOS SEUS TESTES DE API ELIAS NOGUEIRA @eliasnogueira
  • 2.
  • 3.
    FRONTENDBACKEND API Gateway testes funcionaise de aceitação para o frontend web e/ou mobile testes unitários e integração no backend testes na api de consumo
  • 4.
    SUT – SystemUnder Test | Front-end Informar um CPF: • válido • que não esteja com restrição • não cadastrado
  • 5.
    SUT – SystemUnder Test | Front-end Efetuar o cadastro respeitando as restrições
  • 6.
    SUT – SystemUnder Test | Front-end Efetuar operações de CRUD
  • 7.
    Passos... 1 Entender adocumentação da API 2 Pensar nos testes com uma divisão de pipeline 3 Criar uma versão inicial da arquitetura 4 Criar os testes e definir as suítes de testes
  • 8.
  • 9.
    Open API Swagger Ter adocumentação correta e dentro de padrões é a melhor forma de entender a API e iniciar os testes .
  • 10.
    2. Pensar nos testescom uma divisão de pipeline
  • 11.
    API Pipeline Health Check Contrato Funcional Aceitação Garantir queo endpoint está respondendo Garantir que o endpoint não teve seus atributos alterados Garantir que o endpoint funciona ou apresenta os resultados de falha esperados Garantir que um conjunto de endpoints funcionam como na UI
  • 12.
  • 13.
    Modelo 1 Um projetode teste para cada microserviço + um projeto de testes de aceitação Como serão os projetos de teste? BACKEND TEST TEST TEST PROEJTO TESTE TEST PROJETO ACEITAÇÃO
  • 14.
    Modelo 2 Projeto únicopara todas as APIs Como serão os projetos de teste? BACKEND TEST PROEJTO TESTE
  • 15.
    Base Test Ponto centralizadopara pré e pós condições de teste Builder Criação de métodos fluentes Data Factory Criação de dados de forma dinâmica e centralizada Data Driven Estratégia de utilização de dados nos testes Uso de Padrões de Projeto
  • 16.
    4. Criar testes edefinir as suítes de teste
  • 17.
    Rest-Assured http://rest-assured.io DSL Java paratestar e validar APIs REST. import static io.restassured.RestAssured.*; import static org.hamcrest.Matchers.*; public class ExemploRestAssured { @Test public void boasVindas() { given(). param("nome", "Elias"). when(). post("/cadastro"). then(). body("mensagem", is("Olá Elias")); } }
  • 18.
    Rest-Assured http://rest-assured.io DSL Java paratestar e validar APIs REST. import static io.restassured.RestAssured.*; import static org.hamcrest.Matchers.*; public class ExemploRestAssured { @Test public void boasVindas() { given(). param("nome", "Elias"). when(). post("/cadastro"). then(). body("mensagem", is("Olá Elias")); } } importação das bibliotecas necessárias
  • 19.
    Rest-Assured http://rest-assured.io DSL Java paratestar e validar APIs REST. import static io.restassured.RestAssured.*; import static org.hamcrest.Matchers.*; public class ExemploRestAssured { @Test public void boasVindas() { given(). param("nome", "Elias"). when(). post("/cadastro"). then(). body("mensagem", is("Olá Elias")); } } pré-condição para a requisição
  • 20.
    Rest-Assured http://rest-assured.io DSL Java paratestar e validar APIs REST. import static io.restassured.RestAssured.*; import static org.hamcrest.Matchers.*; public class ExemploRestAssured { @Test public void boasVindas() { given(). param("nome", "Elias"). when(). post("/cadastro"). then(). body("mensagem", is("Olá Elias")); } } ação (requisição)
  • 21.
    Rest-Assured http://rest-assured.io DSL Java paratestar e validar APIs REST. import static io.restassured.RestAssured.*; import static org.hamcrest.Matchers.*; public class ExemploRestAssured { @Test public void boasVindas() { given(). param("nome", "Elias"). when(). post("/cadastro"). then(). body("mensagem", is("Olá Elias")); } } validação dos dados de retorno
  • 22.
    API health-check Health Check Contrato Funcional Aceitação Garantir queo endpoint está respondendo Garantir que o endpoint não teve seus atributos alterados Garantir que o endpoint funciona ou apresenta os resultados de falha esperados Garantir que um conjunto de endpoints funcionam como na UI
  • 23.
    heath-check Apenas validamos sea API está disponível Se existir alguma abordagem de verificação ou monitoramento validamos o status geral do retorno @Test(groups = "health") public void healthCheckViaActuator() { basePath = "/actuator"; when(). get("/health"). then(). statusCode(200). body("status", is("UP")); } @Test(groups = "health") public void healthCheckViaAPI() { given(). pathParam("cpf", "81016654049"). when(). get("/restricoes/{cpf}"). then(). statusCode(204); } via monitoramento via API
  • 24.
    API contrato Health Check Contrato Funcional Aceitação Garantir queo endpoint está respondendo Garantir que o endpoint não teve seus atributos alterados Garantir que o endpoint funciona ou apresenta os resultados de falha esperados Garantir que um conjunto de endpoints funcionam como na UI
  • 25.
    ● É onome dado ao pacto entre o produtor e consumidor ● Garante que mudanças na API não invalidem o consumo: ● path ● parâmetros ● dados de envio (request) ● dados de retorno (response body) ● json-schema é um contrato que define os dados esperados, tipos e formatos de cada campo na resposta contrato
  • 26.
    { "nome": "Elias", "idade": 36 } { "$schema":"http://json-schema.org/draft-04/schema#", "type": "object", "properties": { "nome": { "type": "string" }, "idade": { "type": "integer" } }, "required": [ "nome", "idade" ], "additionalProperties": false } json-schema
  • 27.
    { "nome": "Elias", "idade": 36 } { "$schema":"http://json-schema.org/draft-04/schema#", "type": "object", "properties": { "nome": { "type": "string" }, "idade": { "type": "integer" } }, "required": [ "nome", "idade" ], "additionalProperties": false } json-schema possui o nome do atributo e o tipo de dados json-schema
  • 28.
    { "nome": "Elias", "idade": 36 } { "$schema":"http://json-schema.org/draft-04/schema#", "type": "object", "properties": { "nome": { "type": "string" }, "idade": { "type": "integer" } }, "required": [ "nome", "idade" ], "additionalProperties": false } os dois atributos devem estar presentes, obrigatoriamente json-schema
  • 29.
    { "nome": "Elias", "idade": 36 } { "$schema":"http://json-schema.org/draft-04/schema#", "type": "object", "properties": { "nome": { "type": "string" }, "idade": { "type": "integer" } }, "required": [ "nome", "idade" ], "additionalProperties": false } json-schema nenhum outro atributo é permitido
  • 30.
    API funcional Health Check Contrato Funcional Aceitação Garantir queo endpoint está respondendo Garantir que o endpoint não teve seus atributos alterados Garantir que o endpoint funciona ou apresenta os resultados de falha esperados Garantir que um conjunto de endpoints funcionam como na UI
  • 31.
    funcional Validar cenários positivose negativos (caminho feliz | fluxo exceção) @Test(groups = {"funcional"}) public void cPFExistente() { given(). pathParam("cpf", "66414919004"). when(). get("/simulacoes/{cpf}"). then(). statusCode(200). body( "id", equalTo(1), "nome", equalTo("Fulano"), "cpf", equalTo("66414919004"), "email", equalTo("fulano@gmail.com"), "valor", equalTo(11000f), "parcelas", equalTo(3), "seguro", equalTo(true) ); } validação de dados
  • 32.
    API aceitação Health Check Contrato Funcional Aceitação Garantir queo endpoint está respondendo Garantir que o endpoint não teve seus atributos alterados Garantir que o endpoint funciona ou apresenta os resultados de falha esperados Garantir que um conjunto de endpoints funcionam como na UI
  • 33.
    Testar com aperspectiva do usuário ● Acessar a página e efetuar a consulta de restrição no CPF ● Inserir uma simulação de crédito
  • 34.
    aceitação @Test(groups = {"aceitacao"}) publicvoid realizaSimulacaoCredito() { baseURI = "http://localhost"; port = 8088; basePath = "/api/v1"; String cpf = "12345678901"; // efetua a verificacao de cpf restrito given(). pathParam("cpf", cpf). when(). get("/restricoes/{cpf}"). then(). statusCode(204); // efetua a simulacao port = 8089; Simulacao simulacao = SimulacaoDataFactory.criaNovaSimulacao(); given(). contentType(ContentType.JSON). body(simulacao). when(). post("/simulacoes"). then(). statusCode(201); }
  • 35.
    aceitação @Test(groups = {"aceitacao"}) publicvoid realizaSimulacaoCredito() { baseURI = "http://localhost"; port = 8088; basePath = "/api/v1"; String cpf = "12345678901"; // efetua a verificacao de cpf restrito given(). pathParam("cpf", cpf). when(). get("/restricoes/{cpf}"). then(). statusCode(204); // efetua a simulacao port = 8089; Simulacao simulacao = SimulacaoDataFactory.criaNovaSimulacao(); given(). contentType(ContentType.JSON). body(simulacao). when(). post("/simulacoes"). then(). statusCode(201); } requisição de consulta restrição
  • 36.
    aceitação @Test(groups = {"aceitacao"}) publicvoid realizaSimulacaoCredito() { baseURI = "http://localhost"; port = 8088; basePath = "/api/v1"; String cpf = "12345678901"; // efetua a verificacao de cpf restrito given(). pathParam("cpf", cpf). when(). get("/restricoes/{cpf}"). then(). statusCode(204); // efetua a simulacao port = 8089; Simulacao simulacao = SimulacaoDataFactory.criaNovaSimulacao(); given(). contentType(ContentType.JSON). body(simulacao). when(). post("/simulacoes"). then(). statusCode(201); } requisição de simulação de crédito
  • 37.