Testes de APIs REST com Python e Pytest, Parte 2

Neste artigo você vai ver:

Nível: Básico

Conteúdo:

  • Continuação dos verbos HTTP para serviços RESTful (post, delete, put)
  • Criação dos scripts para atualizar e inserir dados em uma API
  • Desenvolver testes e relatórios a partir dos scripts criados

Este é o segundo artigo da nossa série sobre Testes de APIs REST.

Se perdeu o primeiro, importante você entender aqui que o primeiro script criado apenas acessa o endpoint de teste através do método get e exibe seu conteúdo:

python

pytest

Perceba que o objeto resposta.text é uma string grande que contém toda a informação do objeto requests.get e que a mesma pode ser tratada de forma visualmente mais interessante.

Analisando a resposta

Conseguimos extrair a informação de forma mais assertiva e separada convertendo nossa resposta para um dicionário através da função .json() e salvando seu resultado em uma variável que chamei de resposta_dict. Esse dicionário nos possibilita acessar dois valores através de suas respectivas chaves: o status da requisição (sucesso) e o data (com a lista de funcionários). Podemos atualizar nosso código:

testes de api

Imprima os valores contidos nas duas chaves do nosso dicionário separando-os por uma linha de forma que fique mais visível (remova o print antigo):

testes

Execute novamente o comando python get.py no seu terminal (lembre-se que ele deve estar aberto na mesma pasta do script para que o comando funcione corretamente).

teste rest

Sobre o Pytest

O pytest é um framework usado para a criação de testes de maneira dinâmica e rápida.

Seus scripts devem ser desenvolvidos em Python visando a criação de um código pequeno, legível e fácil de dar manutenção. Pode-se gerar diversos tipos de relatórios (html, csv, xml) apenas passando alguns parâmetros na execução da suíte de testes.

Vantagens do Pytest

  • A sintaxe simples permite que pessoas de todos os níveis possam utilizá-lo sem dificuldade;
  • Permite execução de testes em paralelo;
  • Facilidade na troca da execução de um teste, um conjunto ou uma suíte completa;
  • Detecta testes automaticamente baseando-se nos nomes dos arquivos e diretórios criados;
  • Open source.

Convertendo o script para teste do Pytest

  • Os nomes dos scripts de teste do Pytest e seus métodos devem começar com test_ ou finalizar com _test
  • Podemos verificar estados esperados com asserts

Passo a passo

Mude o nome do arquivo de get.py para test_get.py:

Crie um método com o nome de preferência respeitando a nomenclatura citada.  Por conveniência, nomeei o método de test_status_and_data:

tutorial pytest

Passe todo o conteúdo do seu script para o interior desse método através da indentação (note que o import continua inalterado).

Remova os prints e utilize asserts para validar os retornos da API (nesse caso resolvi validar se o status era de sucesso e se a lista de dados não estava vazia através da função len).

Nosso teste só deve passar caso as duas condições sejam verdadeiras.

Agora execute o comando pytest test_get.py e veja o resultado:

pytest test_get.py

Excelente, você conseguiu!

O Pytest nos informou que dentro do arquivo test_get.py foi encontrado um caso de teste que passou e foi executado em 1.63s. A partir de agora é mão na massa, os próximos scripts serão criados de forma mais dinâmica e direta já no formato esperado pelo Pytest.

POST

O próximo passo agora é criar e validar a inserção de um novo empregado na API através do método POST. Veja, de acordo com nosso endpoint, as informações necessárias para essa inserção:

api post

Precisamos do nome, salário e idade (name, salary e age) para criar um novo empregado e devemos guardar essas informações em um dicionário. A coluna Results mostra um status e um id retornados pelo request. Usaremos elas na validação do script.

Vamos inserir mais uma análise nesse script, o status_code da requisição. Como foi dito na primeira parte deste artigo, todos os verbos (quando executados corretamente ou não) nos retornam um código informando o status do request que acabou de acontecer e essa informação fica armazenada no campo .status_code da variável de resposta.

O post deve nos retornar o código 201 quando executado corretamente e vamos inserir nossa validação apenas se obtivermos esse código específico (esse endpoint especificamente nos retorna 200 quando o post acontece com sucesso):

Criar o novo arquivo test_post.py

Importar a biblioteca requests

test post

Criar o método de teste (vou chamá-lo de test_insert_employee)

Crie o cabeçalho conforme o exemplo anterior

rest com python

Crie a nova variável de url com o novo endpoint

método get

Crie o novo funcionário em um dicionário informando name, salary e age (chamarei essa variável de new_employee). Preste atenção que nesse caso específico todas as informações devem ir como texto (mesmo salário que idade sejam do tipo numérico em sua grande maioria).

tutorial api

Realize o request informando ao método get o novo employee (data=new_employee, esse request deverá ser salvo em uma variável para análise futura) e converta a informação para um dicionário.

Insira os asserts para validação da criação correta do novo funcionário caso o status code seja 200 (na maioria das APIs o código de resposta é 201), caso contrário, falhe o teste. Aqui validamos status_code == 200, status == ‘success’ e id válido para o novo funcionário.

Finalmente, nosso código deve ficar assim:

Execute-o com o comando pytest test_post.py e veja o resultado:

Put e Delete

De forma similar aos scripts vistos anteriormente, podemos criar os algoritmos para testar os métodos de Put e Delete. Estes, por sua vez, precisam de um parâmetro (id) para localizar qual funcionário vamos atualizar ou remover.

Mas agora, vamos utilizar outro endpoint (veja aqui) para continuar desenvolvendo novos scripts. Esse novo endpoint trata de publicações simples (artigos, tweets, etc) e seu corpo conta com com id próprio, id do usuário, título da publicação e corpo de texto. Quando chamado através do método put, nos retorna o status_code e o objeto cujas informações atualizamos: id (int), title (str), body (str) e userId (str).

routes testes

Quando chamado através do método delete, nos retorna apenas o status_code informando se a remoção foi bem sucedida ou não.

Put

  • Crie o arquivo test_put.py
  • Importe a biblioteca requests
  • Crie o método test_put_new_data
  • Crie uma variável para guardar o id do do post
  • Crie a nova variável de url com o novo endpoint 
  • Crie o objeto com as informações que deseja atualizar em um dicionário (eu resolvi chamar essa variável de new_data)
  • Realize o request de acordo com o exemplo do post, mas não se esqueça do cabeçalho e lembre-se de concatenar ao fim da url o id do post que deseja atualizar e converta a informação retornada pelo request em um dicionário.
  • Insira o assert para validação da atualização correta do post caso o status code seja 200, e, caso contrário, falhe o teste. Aqui validamos se o objeto retornado atualizado é igual ao objeto enviado pelo put.

python e pytest

Execute o script com o comando pytest test_put.py e veja o resultado:

pytest test_put.py

Delete

Por fim, podemos acessar o endpoint através do método delete e remover um ou mais registros. Nesse caso específico basta informar a url, o id (concatenado à url) e o método:

endpoint
  • Crie o arquivo test_delete.py
  • Importe a biblioteca requests
  • Crie o método test_delete_data
  • Crie uma variável para guardar o id do do post que será deletado
  • Crie a nova variável de url com o novo endpoint 
  • Realize o request de acordo com o exemplo do put (sem a necessidade do parâmetro data) e converta a informação retornada pelo request em um dicionário.
  • Insira o assert para validação do status_code == 200.
api

Execute o script com o comando pytest test_delete.py e veja o resultado:

Na continuação desta série, veremos mais formas de validar os testes, executar todos os scripts de uma vez em uma suíte de testes e criar relatórios visualmente mais interessantes.

Tem sugestões ou dúvidas sobre o assunto? Deixe nos comentários! 

Newsletter de tecnologia

Aproveita pra assinar aqui nossa newsletter semanal de tecnologia e receber em primeira mão nossos conteúdos.

5e5eb9a15243441138e27637_marlon-de-alencar
Analista de Testes
Engenheiro de computação, mestrando em Ciências de Computação e jogador de Dota nas horas vagas.

Este site utiliza cookies para proporcionar uma experiência de navegação melhor. Consulte nossa Política de Privacidade.