Testes em Python III — Testando o End Point de sua API com teste de contrato
Usando Json Schema para garantir sua API
Aqui vamos imaginar uma situação onde você montou uma API, fez muitos testes unitários e tudo anda muito bem.
Só que você precisa garantir que a saída de dados da sua API está 100% e para isso você precisa de um teste de integração e/ou sanidade no seu sistema.
Atualmente estou criando uma API que faz a junção de seis outros serviços para fazer entrega de conteúdo a aplicativos e por isso eu preciso garantir que minha saída esteja sempre intacta, não dá para ficar mandando novas versões de APPs para loja porque a API muda, o fato de servir mais de um aplicativo também exige que os end points jamais sejam alterados.
Como a quantidade de serviços consumidos é muito grande, ficou inviável fazer uma cópia de cada um deles para criar um ambiente de testes. E mesmo que eu tivesse esse ambiente, se alguém mudar alguma coisa do lado de lá eu não saberia e quebraria meu sistema. Eu sei que não é minha responsabilidade testar outros serviços dentro dos meus testes, mas e se eu puder ter um teste que conseguisse garantir que naquele momento todo o ambiente está funcionando, seria bem legal, certo?
Então tomei a decisão de não criar todo um sistema de seis serviços isolados para garantir o meu teste de integração, o fato de eliminar um problema me causou outro. Como eu vou garantir que as informações da minha API estão corretas?
A primeira coisa que vem à cabeça quando se fala em testes de integração é fazer alguma coisa assim:
Legal, mas se eu não tenho um ambiente controlado o que me garante que o name
terá o valor Ricardo
? Alguém pode ir no serviço de cadastro e mudar para Daniel, meu teste começa a quebrar e seria impossível continuar assim.
Bom, aí veio o pensamento… Qual a importância de testar se o name
é Ricardo
? Na verdade, o importante no seu teste é se name
tem uma string
independente de qual seja. Isso vale para image
, onde o que importa é se o valor é uma url
. Com esse novo pensamento eu comecei a desenvolver um teste de contrato usando json-schema.
Vou mostrar como funciona mostrando exemplos de código Python para isso vamos usar o jsonschema que vai fazer a validação dos esquemas para nossos jsons.
Criar um esquema para validar jsons nada mais é do que dizer o que cada campo pode conter, se é obrigatório ou não, se está no formato correto, etc.
Vamos validar o campos name
que nesse caso é obrigatório e deve ser do tipo string
. Isso escrito no formado do json-schema fica da seguinte forma:
No json acima nós identificamos que vamos validar um object
que tem uma propriedade name
do tipo string
, também falamos que esse object
tem uma lista de propriedades obrigatórias, e nós colocamos name
nessa lista.
Para fazer uma validação completa do modelo de informação de usuários da nossa API precisamos do schema
completo. Veja abaixo como seria o teste completo:
O json a ser validado pode ser o retorno da sua API, para ficar mais simples de entender o schema, que é o foco aqui, eu coloquei um json dentro da variável data
e criar o esquema do json na variável schema
. No final, fiz a validação com o método validate
.
Passo a passo no esquema:
type
define que o meu json é um objeto. Esse é o mais fácil de entender.- A primeira coisa a se notar é o
"required": ["name"]
, ele define que do meu json, apenas oname
é obrigatório. - Em
properties
nos temos as definições para validar cada campo do nosso json. name
está com"type": "string"
. Nada mais alem do tipo será validado.image
é do tipostring
, mas aqui nós usamosformat
para dizer que ela tem que ser uma string no formato de umauri
.age
é um número inteiro, eu coloquei umminimum
e ummaximum
apenas para mostrar que eles existem, nem sei se seria o ideal para um campo de idade.birth_date
é do tipostring
e usa oformat
para definir que ele é umdate-time
.
Existem muitas outras opções para se utilizar esse tipo de validação, mas acho que para um primeiro contato já foi o suficiente.
Um teste funcionando com essa validação pode ser encontrado no nosso projeto base dessas publicações aqui. Para verem a validação melhor, baixem o projeto e mudem o json forçando os erros no teste.
Um detalhe, para alguns formatos funcionarem na validação você vai precisar de pacotes extras, nesse exemplo precisei instalar o strict-rfc3339 para validar o date-time
e o rfc3987 para validar uri
. Eles estão no requirements.txt
do nosso projeto.
Com isso agora, quando eu rodo um teste completo na minha API ela vai em todos os serviços necessários e me retorna um valor, eu bato esse valor com o esquema criado para ele e isso garante totalmente que minha API vai cumprir com o contrato estabelecido com os aplicativos.
Espero que tenham gostado e não deixem de me procurar para tirar qualquer dúvida, sugerir algum assunto e o mais importante, corrigir qualquer besteira que eu tenha escrito aqui, ok!?