Testes em Python III — Testando o End Point de sua API com teste de contrato

Usando Json Schema para garantir sua API

Ricardo Baltazar
Editora Globo
4 min readJul 22, 2018

--

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:

Um possível teste de integração

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 o name é 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 tipo string , mas aqui nós usamos format para dizer que ela tem que ser uma string no formato de uma uri .
  • age é um número inteiro, eu coloquei um minimum e um maximum apenas para mostrar que eles existem, nem sei se seria o ideal para um campo de idade.
  • birth_date é do tipo string e usa o format para definir que ele é um date-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!?

--

--