Pular para conteúdo

Estratégia de testes

O projeto separa quatro tipos de evidência. A localização sob tests/integration/ não significa, por si só, acesso à rede: o replay de fixtures também mora ali, mas é determinístico e usa mocks.

Mecanismo O que verifica Dependências Efeito externo
Unit tests Domínio, aplicação, handlers, adapters, concorrência pytest, mocks, moto; HTTP simulado nos adapters Não previsto pelos testes unitários
Integration tests Prompts e decisões de agentes em chamadas reais OpenAI real e bundle de dependências configurado Custo OpenAI; outros providers podem ser ativados pela configuração
Fixture replay Uma conversa completa com respostas LLM gravadas e invariantes esperadas moto e stubs explícitos Sem OpenAI real
Smoke Configuração, conectividade e contrato operacional de um provider Credenciais e ambiente real conforme alvo Leituras de rede e, com flags, envios/escritas

Execução local sem chamadas reais

Com Python 3.12 e o ambiente do projeto ativo:

python -m pip install -e ".[dev]"
python -m pytest tests/unit tests/integration/test_fixture_replay.py -q

Uma seleção equivalente para excluir os cenários OpenAI é:

python -m pytest -m "not integration" -q

O comando por caminhos é mais explícito sobre o conjunto esperado. --no-cov desliga a coleta se ela tiver sido adicionada por configuração externa; o addopts versionado contém apenas -ra --strict-markers.

Seleção de testes e credenciais

tests/integration/test_scenarios.py só é ignorado automaticamente quando OPENAI_API_KEY está ausente. Executar pytest sem filtro com uma chave exportada pode chamar OpenAI. O README histórico apresenta a execução ampla como gratuita; a seleção acima documenta o comportamento atual com segurança.

Convenções e interpretação

pyproject.toml registra os markers unit, integration e fixture_replay. Os markers unit e fixture_replay não estão aplicados uniformemente; o próprio test_fixture_replay.py usa parametrização sem marker de replay. Não use -m unit ou -m fixture_replay como substituto da seleção por diretório/arquivo.

passed afirma apenas que as asserções daquele conjunto passaram. skipped significa que um cenário não rodou; deselected indica exclusão pelo filtro. Uma falha em limiar de cobertura é diferente de falha funcional. A contagem e o percentual publicados no README e documentos históricos são fotografias antigas, não resultados desta documentação.

Onde adicionar regressões

Alteração Teste principal
Parser, actions ou transições tests/unit/application/test_parser.py, test_action_mapping.py; tests/unit/domain/test_states.py
Prompt e contrato do invocador tests/unit/agents/test_system_prompts.py, test_invoker.py
Orquestração e latest-message-wins tests/unit/application/test_process_message_use_case.py; tests/unit/lambdas/test_orchestrator.py
Webhook e recibos tests/unit/lambdas/test_webhook_handler.py
Persistência e condições tests/unit/integrations/test_dynamodb_repos.py
CRM durável tests/unit/application/test_crm_sync.py, tests/unit/lambdas/test_crm_sync.py
Atendimento humano tests/unit/application/test_human_conversation.py; tests/unit/lambdas/test_emulator.py
Contrato HTTP de provider Arquivo test_*_client.py em tests/unit/integrations/
Conversa que regrediu Fixture em tests/fixtures/conversations/ com o mínimo de turnos que reproduz a falha

Detalhes: unitários, integração real, fixtures, smokes.