Testes de Contrato utilizando Python

Ketlin Pedron
8 min readSep 20, 2020

--

Este é o Quarto e Último Post da série: Testes de Contrato utilizando Python

Photo by Ben Stern on Unsplash

No subtítulo você pode perceber que estou citando que este artigo é o último de uma série. Acontece que, ao invés de criar direto o artigo sobre Testes de Contrato, eu optei por criar artigos introdutórios, para ajudar o melhor entendimento do projeto que irei apresentar aqui. Você pode ler sobre a motivação para utilizar testes de contrato, Spotify Web API usando Postman e Python Requests & Spotify Web API, se achar conveniente.

Portanto, neste artigo, não irei detalhar alguns conceitos que foram já vistos nos artigos mencionados.

Um pouco sobre esta Estratégia de Qualidade

Testes de contrato servem para validar a saúde de contratos que foram combinados entre um cliente e um fornecedor. Em um mesmo projeto, o backend é o principal fornecedor do frontend, desta forma, teremos contratos “internos”. Uma outra visão, é quando o backend da minha aplicação precisa utilizar serviços externos, neste caso teremos contratos “externos”.

Em ambos os casos, quem está consumindo endpoints precisa entender que mudanças repentinas devem ficar no radar do time, porque qualquer alteração que não tenha sido avisada, pode ocasionar em falhas na aplicação, o que pode prejudicar a experiência do usuário.

Então, o que queremos com Testes de Contrato é:

  • O rápido feedback para o time, quando o parceiro alterou um contrato.
  • O rápido feedback para o time de estratégia, quando o parceiro está fora do ar (em casos de contratos “externos”).
  • Trazer mais confiança para o time, a medida que novos cenários de testes são mapeados.

Para alcançar estes objetivos, você pode criar um projeto de testes de contrato, com diferentes casos de testes utilizando o endpoint da web api externa. Tudo isso poderá ficar rodando em um servidor, em uma determinada frequência durante o dia. Caso algum teste venha a falhar, ou algum serviço esteja indisponível, você pode configurar reports automáticos para serem enviados aos interessados do projeto. Com isso, não apenas o desenvolvedor de testes irá monitorar, mas todo o time 😏

Usando Spotify como exemplo

Tomemos como exemplo uma aplicação utilizando o Spotify como serviço parceiro e externo.

Digamos que você está desenvolvendo uma aplicação e por algum motivo esta aplicação irá consumir a Web API do Spotify, vamos então criar o Contrato entre sua aplicação e a Web API. Em nosso contrato, será acordado que a aplicação irá consumir dois endpoints iniciais, relacionados à Criação de Playlists e Visualização de Playlists.

No artigo 2 da série, você pôde ver para estes endpoints quais eram os parâmetros das requests e qual o formato das response. Pois bem, iremos utilizá-los aqui novamente. Nesta estratégia, o grande ponto forte é validar o formato das respostas, ou seja, se informações que eu preciso consultar estão no formato esperado, tanto do tipo de dados (strings, números, objetos) quanto das chaves do objeto da resposta.

1. Criando o projeto

Novamente, minha sugestão de estrutura de projeto é a seguinte:

A diferença desta estrutura para a do artigo 3, é que acrescentei a pasta Schemas. Esta pasta será responsável por armazenar nossos arquivos json schemas, o schema é um formato json onde configuramos uma estrutura desejada para um documento json que já conhecemos. Utilizamos este validador porque quando recebemos uma response, podemos converter ela em um .json para poder analisar a estrutura do response que recebemos (pulo do gato, não? 😸). As demais pastas do projeto seguem a estratégia adotada no artigo 3.

2. Criando os Schemas

O primeiro arquivo que irei criar será para validar o formato da response vinda do endpoint de playlists (playlists_schema.json). Para tentar deixar mais fácil de você visualizar, eu tentei quebrar o arquivo em alguns blocos, que representam um array ou um dicionário.

  • type - Define o tipo de objeto que vem a seguir, em nosso exemplo utilizamos object (para dicionário) e array (para uma lista de itens). O type também é utilizado para informar o tipo de um campo no json, por exemplo observe o campo description, ele é do tipo string.
  • properties - Define quais são os itens dentro de um dicionário. Um properties é criado toda vez que um campo do json for do tipo object, dentro dele você colocará todos o campos do objeto.
  • items - Mesmo objetivo do properties, porém para um array.
  • additionalProperties - É um parâmetro utilizado toda vez que precisamos forçar que parâmetros adicionais não serão aceitos. Isso faz com que caso a response um dia seja enviada com novos campos no objeto, a validação falhe. O additionalProperties deve ser adicionado dentro de um objeto, ao mesmo tempo que estamos criando o properties dele.

Observe o trecho do arquivo que eu destaquei na imagem. Neste pedaço podemos ver um exemplo de tudo o que falei acima.

Podemos resumir o trecho de código que está destacado na imagem: Tracks é um campo do objeto principal da response, tracks é do tipo objeto também e possui os seguintes campos: href (do tipo string) e total (do tipo number). Em tracks não serão aceitos campos adicionais. 👊

Obs.: Esta response vimos no artigo 2 e artigo 3.

Para instalar o json schema no seu projeto, execute:

pip install jsonschema

3. Pastas Requests e Resources

O conteúdo das pastas Requests e Resources foram discutidos no artigo 3, iremos utilizar os mesmos arquivos e os mesmos conceitos. Porém, se você ainda não criou seu projeto, você pode ler o artigo ou consultar o projeto no meu GitHub.

A única novidade vai ser a criação de uma função nova, para abrir e ler os arquivos json schemas, dentro do utils.py:

4. Configurando o primeiro caso de teste

Usando como base o arquivo test_playlists.py do artigo 3 e o método de teste test_get_playlists, vamos criar o seguinte caso de teste:

Nosso teste funcionará da seguinte forma: Primeiro a request será enviada, solicitando a lista de playlist’s do meu usuário, então será validado se o status code retornou 200. A próxima etapa do teste é carregar o arquivo playlists_schema.json e armazenar em uma variável. Após isso, o método validate da biblioteca jsonschema do Python, compara se o conteúdo da response está válido de acorto com o playlist_schema.json. Caso a validação falhe, o pytest irá imprimir uma mensagem de erro.

Se você chegou até aqui, ao rodar seu teste via terminal, deverá obter sucesso. Não lembra como executar? Use pytest test_playlists.py

5. Simular uma falha

Bom, existe uma forma de confirmar que a validação do schema da response está realmente executando. Vamos fazer o seguinte: vá novamente no arquivo playlists_schema.json e altere o tipo do campo description para número, ficando desta forma:

Rode novamente o teste via terminal, agora deverá falhar:

O teste falha porque o campo description é a descrição de uma playlist e é enviado com uma string dentro. Veja ele na visão no Postman:

6. Incrementando os testes

Vamos criar um novo teste, agora criando uma nova playlist e validando também o retorno da response. Adicione o novo método de teste:

Perceba que a lógica é a mesma: Formular e enviar a request, validar o status code e, por último, validar o schema. Também, criei um novo arquivo de schema responsável por configurar o formato da response do endpoint de criação de playlist. Você poderá consultar este novo arquivo no GitHub.

Execute novamente o teste. Agora você verá dois testes executando com sucesso.

7. O que seria o próximo passo?

Após incrementar o projeto de testes e entender bem como funciona o Json Schema, recomendo que você configure seu projeto no Jenkins, e o configure para todar algumas vezes ao dia. Isso simula o ambiente real de um projeto: o Teste de Contrato irá rodar periodicamente, a fim de monitorar os contratos.

Até a presente data eu não consegui criar um artigo que mostre como fazer esta etapa, mas prometo que assim que eu conseguir um tempinho publico e atualizo aqui o link, beleza? 👊

Conclusões

Bom, o que vimos de exemplo foi somente duas das possibilidades de teste de uma Web API (Spotify), que possui muitos outros recursos que podem ser explorados. O próximo passo pode ser adicionar novos testes relacionados à criação de playlist, editar perfil de usuário, realizar buscar, entre outros. Deixo também como sugestão tentar criar este projeto, que vimos desde o artigo 3, em uma outra linguagem. A ideia do projeto e a linha de raciocínio para criação dos testes é a mesma, o que mudará serão os desafios a serem vencidos utilizando outra linguagem e outras bibliotecas.

Minha ideia para este série de artigos, foi que o leitor pudesse encontrar um material que possa exemplificar testes de API, desde o entendimento sobre uma Web API, utilizar Postman para validações iniciais e concretizar tudo em um projeto automatizado. Também, a possibilidade de criar um projeto de Testes de Contrato utilizando uma linguagem de programação, de forma prática e funcional.

Acredito que estes objetivos foram alcançados e que, a partir de agora, você leitor possui uma boa base para procurar mais informações e possibilidades sobre Testes de Contrato, e decidir junto com seu time qual a melhor forma de implementar este tipo de estratégia dentro de seus projetos.

Caso surjam dúvidas sobre tudo o que vimos ou sugestões, fique à vontade para se conectar comigo através do LinkedIn. AHHH, lembrando que todos os códigos vistos nos artigos estão disponíveis em: https://github.com/kpedron

Abraços, e até a próxima. 😸

--

--

Ketlin Pedron

Tendo experiência como developer e QA, tem a missão de contribuir nos times para que a Qualidade esteja presente, desde o início até a última entrega.