No desenvolvimento de testes de API, a automação eficiente requer gerenciamento de estados, como sessões de autenticação. Utilizando pytest e a biblioteca requests, é possível configurar fixtures para reutilizar conexões e tokens, evitando logins repetidos.
Configuração de Fixtures para Condições de Teste
Fixtures no pytest permitem preparar dados e recursos antes dos testes. Para APIs que necessitam de autenticação, podemos criar uma sessão persistente com o token obtido no login, garantindo que todas as requisições subsequentes utilizem as mesmas credenciais.
Exemplo de Endpoints de API
Considere os seguintes endpoints fictícios para uma aplicação de tarefas:
- Listar tarefas: GET https://api.exemplo.com/v1/tarefas
- Login: POST https://api.exemplo.com/v1/autenticacao com corpo {"senha": "senha_segura", "email": "usuario@exemplo.com"}
- Criar tarefa: POST https://api.exemplo.com/v1/tarefas com corpo {"titulo": "", "concluida": false}
- Atualizar tarefa: PUT https://api.exemplo.com/v1/tarefas/{id_tarefa}
- Excluir tarefa: DELETE https://api.exemplo.com/v1/tarefas/{id_tarefa}
O código 401 indica falta de autenticação. Em testes manuais, cada requisição poderia exigir um novo login, mas fixtures automatizam esse processo.
Criando uma Sessão Autenticada com Login Automático
Em vez de obter um token para cada teste, configuramos uma fixture com escopo de sessão que realiza o login uma vez e reutiliza a conexão.
import pytest
import requests
@pytest.fixture(scope="session")
def criar_sessao():
return requests.Session()
@pytest.fixture(scope="session")
def sessao_autenticada(criar_sessao):
"""Realiza login automático e configura o cabeçalho de autorização."""
credenciais = {"senha": "senha_segura", "email": "usuario@exemplo.com"}
resposta = criar_sessao.post(
"https://api.exemplo.com/v1/autenticacao",
json=credenciais
)
assert resposta.status_code == 200
token = resposta.json()["token_acesso"]
criar_sessao.headers["Authorization"] = f"Bearer {token}"
return criar_sessao
Ao usar sessao_autenticada nos testes, a autenticação é aplicada automaticamente. Os benefícios incluem reutilização de conexões TCP e manutenção persistente dos cabeçalhos.
Testes Utilizando a Sessão
def test_obter_tarefas(sessao_autenticada):
"""Verifica se a listagem de tarefas retorna status 200."""
resposta = sessao_autenticada.get("https://api.exemplo.com/v1/tarefas")
assert resposta.status_code == 200
def test_criar_tarefa(sessao_autenticada):
"""Cria uma nova tarefa e valida o status."""
dados_tarefa = {"titulo": "Nova tarefa", "concluida": False}
resposta = sessao_autenticada.post(
"https://api.exemplo.com/v1/tarefas",
json=dados_tarefa
)
assert resposta.status_code == 200
Lidando com Estados Não Autenticados
Para testes que requerem acesso sem login, crie uma sessão independente por teste.
@pytest.fixture
def sessao_sem_autenticacao():
return requests.Session()
def test_acesso_nao_autorizado(sessao_sem_autenticacao):
"""Tenta acessar uma API protegida sem token."""
resposta = sessao_sem_autenticacao.get("https://api.exemplo.com/v1/tarefas")
assert resposta.status_code == 401
Associação entre Interfaces com Fixtures
Testes de atualização ou exclusão exigem que uma tarefa já exista. Use fixtures para criar dados de teste e retornar identificadores necessários.
@pytest.fixture
def criar_tarefa_para_teste(sessao_autenticada):
"""Cria uma tarefa temporária e retorna seu ID."""
payload = {"titulo": "Tarefa temporária", "concluida": False}
resposta = sessao_autenticada.post(
"https://api.exemplo.com/v1/tarefas",
json=payload
)
assert resposta.status_code == 200
return resposta.json()["id"]
def test_atualizar_tarefa(sessao_autenticada, criar_tarefa_para_teste):
"""Atualiza a tarefa criada pela fixture."""
id_tarefa = criar_tarefa_para_teste
novos_dados = {"titulo": "Tarefa atualizada", "concluida": True}
resposta = sessao_autenticada.put(
f"https://api.exemplo.com/v1/tarefas/{id_tarefa}",
json=novos_dados
)
assert resposta.status_code == 200
Dados Dinâmicos e Teste Orientado a Dados
Para variar dados de teste, carregue informações de fontes externas como arquivos CSV, YAML ou bancos de dados. Após o carregamento em Python, os dados se tornam estruturas como listas ou dicionários.
Por exemplo, usar a biblioteca openpyxl para ler dados de planlihas Excel:
pip install openpyxl
Funcionalidades de um Framework de Teste de API
Um framwork robusto deve:
- Automatizar a autenticação e gestão de sessões.
- Suportar dados dinâmicos via parâmetros.
- Registrar respostas de API para aálise.
- Integrar fontes de dados variadas.
- Fornecer suporte a mockagem de APIs.
- Permitir alternância entre ambientes de teste.