Melhores Práticas de Teste
Regras para uma suíte pytest que seja rápida, confiável e de fácil manutenção.
Como Usar Esta Lista
- Aplique ao escrever novos testes ou revisar Pull Requests (PRs)
- Priorize isolamento e velocidade antes da porcentagem de cobertura
- Reavalie ao adicionar testes de integração ou E2E (End-to-End)
A - Design de Testes
- Um comportamento por teste. Cada teste falha por exatamente um motivo.
- Estrutura Arrange-Act-Assert (Organizar-Agir-Afirmar). Legível sem comentários explicando o layout.
- Nomes de teste descritivos.
test_discount_over_100_raises(teste_desconto_acima_de_100_levanta_excecao), nãotest_discount_3(teste_desconto_3). - Teste o comportamento, não a implementação. Afirme saídas e a API pública, não chamadas internas.
B - Isolamento e Velocidade
- Sem rede em testes unitários. Use mock para HTTP, DNS e APIs externas.
- Estado de banco de dados novo por teste. Reverte transações ou use SQLite em memória.
- Sem
sleep()para controle de tempo. Use mocks para tempo ou espera baseada em eventos. - Marque testes lentos.
@pytest.mark.slow(marcar como lento) é excluído da execução padrão de CI.
C - Fixtures e Dados
- Configuração compartilhada em fixtures, não copiar e colar. Use
conftest.pypara reutilização. - Fixtures de fábrica para dados flexíveis.
user_factory(email="...")em vez de dicionários estáticos. - Escopo de função por padrão. Escopos mais amplos apenas para configuração imutável cara.
- Parametrize casos conhecidos; Hypothesis para exploração. Não use loops dentro dos testes.
D - CI e Cobertura
- pytest executa em todo PR. Verificação obrigatória, não opcional.
- Cobertura apenas em
src/. Limite de 80%; maior para módulos de autenticação e faturamento. - Cobertura de branch habilitada.
branch = truena configuração de cobertura. - Matriz multi-versão para bibliotecas. Teste os limites de
requires-pythoncom nox ou matriz de CI.
E - Manutenção
- Exclua testes para funcionalidades removidas. Testes mortos escondem cobertura ausente.
- Corrija testes instáveis imediatamente. Quarentena com
@pytest.mark.flaky(marcar como instável) apenas como medida temporária. - Use mock nas fronteiras, não em todo lugar. Muitos mocks significam testar mocks.
- Testes de integração separados dos testes unitários. Diretórios
tests/unit/etests/integration/.
FAQs
Quão rápidos devem ser os testes unitários?
Suíte unitária completa abaixo de 60 segundos. Testes individuais abaixo de 100ms.
Qual a proporção de testes unitários para integração?
Aproximadamente 80/20. A maioria dos testes são unitários; integração cobre caminhos críticos.
Devo testar funções privadas?
Teste através da API pública. Funções auxiliares privadas são cobertas indiretamente.
Como lidar com arquivos de dados de teste?
Use tests/fixtures/data/ com o caminho via pathlib.Path(__file__).parent.
Teste de Snapshot?
Útil para serializadores e templates. Revise atualizações de snapshot cuidadosamente em PRs.
Quantas asserções por teste?
Um comportamento lógico. Múltiplas asserções são aceitáveis se verificarem um único resultado.
Testes devem usar HTTP real?
Unitários: não. Integração/staging: sim, contra o ambiente de teste.
Como testar logging?
Fixture caplog: with caplog.at_level(logging.ERROR):.
Testes paralelos?
pytest-xdist -n auto para suítes grandes. Garanta o isolamento dos testes primeiro.
Quando pular um teste?
Use @pytest.mark.skip (marcar como pulado) com um motivo para casos específicos de plataforma ou trabalho inacabado. Não use para testes que falham.
Relacionados
- Configuração do pytest - configuração
- Asserções e Estrutura de Teste - layout de teste
- Cobertura e Relatórios - política de cobertura
- Mocking e Patching - fronteiras de isolamento
Versões das Pilhas: Esta página foi escrita para Python 3.14.0, FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, e uv 0.6+.