Testes unitários e AWS simulada¶
O conjunto em tests/unit/ inclui testes puros e testes de componentes que acessam boto3 sob moto. Moto implementa serviços AWS em memória durante o teste; ele permite verificar chaves, transações e condições dos repositories sem provisionar uma tabela real. Isso não comprova IAM, limites, consistência temporal ou latência de produção.
Ferramentas e fixtures compartilhadas¶
tests/conftest.py fornece:
| Fixture | Contrato |
|---|---|
dynamo_table |
Cria tabela gogenetic-agent-test, PK/SK, GSI1 com projeção ALL e TTL ttl; entrega o recurso boto3 dentro de mock_aws() |
aws_env |
Cria tabela e fila FIFO; configura env mínimo, chave OpenAI de teste e admin de teste; limpa cache de load_settings() antes/depois |
_strip_aws_endpoint_override |
Autouse: remove AWS_ENDPOINT_URL, AWS_ENDPOINT_URL_DYNAMODB, AWS_ENDPOINT_URL_SQS durante cada teste para não desviar boto3 de moto |
Testes de adapters simulam respostas HTTP e erros; testes de agentes usam invocadores/LLM fake. A suite de aplicação injeta dependências para observar estado, chamadas e persistência. Ao criar teste, injete o provider falso explicitamente em vez de depender do valor do .env do desenvolvedor.
Comandos¶
Depois de ativar o ambiente Python na raiz:
# Conjunto unitário
python -m pytest tests/unit -q
# Arquivo relevante à alteração
python -m pytest tests/unit/application/test_human_conversation.py -v
# Teste individual existente
python -m pytest tests/unit/application/test_human_conversation.py::test_successful_send_reports_transcript_failure_without_raising_or_retrying -v
# Filtro por nome, interrompendo na primeira falha
python -m pytest tests/unit/lambdas/test_webhook_handler.py -k "duplicate or signature" -x -v
# Cobertura de branches do core e shared, com linhas faltantes
python -m pytest tests/unit tests/integration/test_fixture_replay.py --cov --cov-report=term-missing --cov-report=html
O relatório HTML é escrito em htmlcov/index.html. A configuração de cobertura mede src/core e src/shared, habilita branches e exige fail_under=80. Portanto 80% é o limiar configurado, não evidência de percentual obtido. Handlers fora dessas duas árvores não estão incluídos nessa métrica, embora tenham testes.
Falhas úteis¶
| Falha | Interpretação e próxima investigação |
|---|---|
AssertionError em estado |
Comparar action retornada, dados necessários e transição esperada |
ConditionalCheckFailedException inesperado |
Conferir versão/estado anterior, recibo vigente e expressão condicional |
EndpointConnectionError para localhost |
Confirmar execução via pytest com tests/conftest.py; não apontar moto a DynamoDB Local |
ModuleNotFoundError: core |
Instalar projeto editável no mesmo Python utilizado pelo pytest |
ModuleNotFoundError: moto/httpx |
Instalar extra dev, verificar venv ativo |
| Gate de coverage falha, testes passam | Ver linhas/branches não cobertos e fonte medida; não declarar suite totalmente aprovada |
Testes que preservam efeitos externos¶
test_pending_send_claims_before_whatsapp_and_logs_operator_message verifica que assumir precede o envio humano. test_live_send_lock_rejects_a_second_collaborative_send protege contra concorrência; test_successful_send_reports_transcript_failure_without_raising_or_retrying impede reenvio após entrega real já concluída. Essas verificações são mais importantes que comparar somente a string exibida.
tests/unit/application/test_smokes.py testa que WhatsApp, eGestor e SES não enviam/escrevem sem permissão. Isso valida os guards do runner com mocks, não o funcionamento real desses serviços.
Ao alterar comportamento, adicione a regressão no menor nível que expresse o problema e rode o conjunto relacionado. Não atualize expectativas apenas para fazer uma falha desaparecer: revise contrato, causa e efeito sobre o fluxo de mensagens.