# 🧪 Documentação da Suíte de Testes Automatizados Este diretório contém a suíte completa de **247 testes automatizados** com **100% de aprovação**, cobrindo testes unitários, testes de integração de pipeline, testes de regressão, contratos de CLI, provas de sensibilidade por mutação e testes End-to-End (E2E) com chamadas reais ao vivo para modelos de linguagem (LLM). --- ## 📊 Inventário e Mapa de Cobertura das Suítes | Arquivo de Teste | Qtd. Testes | Escopo / O que valida? | |---|:---:|---| | [`test_classify_exhaustive_suite.py`](test_classify_exhaustive_suite.py) | **38** | **Suíte Exaustiva (QA Sênior)**: Todos os caminhos felizes (canônico, aliases, repetição, grafo), infelizes (homônimos, domínio sem alvo, empate de negativas), limiares/ambiguidade (`TANGENTIAL`), fallback LLM (upgrades, confirmações, rejeições, erros 500, timeouts, parsing resiliente, clipping de confidence), contratos de CLI e matriz multilíngue de 6 idiomas. | | [`test_e2e_text_analysis_pipeline.py`](test_e2e_text_analysis_pipeline.py) | **13** | **Funil Ponta a Ponta**: Validação completa do pipeline de texto (NLP determinístico $\rightarrow$ Ambiguidade $\rightarrow$ Fallback LLM $\rightarrow$ Degradação Graciosa) e teste de integração ao vivo (`test_funnel_live_api_execution_if_configured`) contra a API real (OpenAI / Omniroute / Gemini). | | [`test_llm_fallback.py`](test_llm_fallback.py) | **9** | **Módulo LLMFallbackAdapter (Tier 3)**: Validação da engenharia de prompt (`build_prompt`), detecção de disponibilidade, parsing JSON (puro e em blocos ````json ... ````), acionamento por limiar de confiança e resiliência a exceções. | | [`test_convert_article_to_markdown.py`](test_convert_article_to_markdown.py) | **67** | **Conversor JSON $\rightarrow$ Markdown (Spec 005)**: 100% dos requisitos funcionais (FR-001 a FR-018), matriz de prioridade de 11 campos de metadados, isolamento estrito de extratores, conversão ATX, remoção de headers duplicados e gravação atômica transacional. | | [`test_select_article_extractor.py`](test_select_article_extractor.py) | **30** | **Seletor Determinístico de Extrator (Spec 004)**: Cálculo de consenso $F_1$ n-gram, pontuação multi-critério (título, autor, data, corpo, imagens), isolamento de empates e enriquecimento com `selected_extractor`. | | [`test_extract_article_contents.py`](test_extract_article_contents.py) | **15** | **Extrator Multimotor (Spec 003)**: Scraping simultâneo via Trafilatura, Newspaper4k e Readability, isolamento de falhas individuais e fallbacks intra-motor (`markdown`/`html` $\rightarrow$ `text`). | | [`test_extract_google_news.py`](test_extract_google_news.py) | **16** | **Extrator Google News RSS (Spec 002)**: Parsing de feed RSS, motor anti-bot Foxcape headless, resolução paralela de URLs reais intermediárias e suporte a locales internacionais. | | [`test_benchmark_24.py`](test_benchmark_24.py) | **24** | **Matriz Canônica de Benchmark (Spec 001)**: 24 cenários controlados cobrindo **6 idiomas** (`pt`, `en`, `es`, `de`, `it`, `fr`) $\times$ **4 categorias de decisão** (`DIRECT_INHERENT`, `CONTEXTUAL_INHERENT`, `TANGENTIAL`, `NOT_RELATED`). | | [`test_adversarial.py`](test_adversarial.py) | **7** | **Testes Adversariais e Edge Cases**: Injeção de caracteres especiais, emojis, textos maciços, documentos sem quebra de linha, falsos cognatos e metáforas linguísticas. | | [`test_classifier.py`](test_classifier.py) | **5** | **Núcleo de Regras Determinísticas**: Asserções fundamentais do classificador Tier 1 sobre o ECP da Petrobras. | | [`test_cli.py`](test_cli.py) | **5** | **Interface CLI Básica**: Contratos de argumentos (`--ecp`, `--content`, `--output`), saída padrão formatada e captura de erros em `stderr`. | | [`test_language.py`](test_language.py) | **8** | **Módulo de Idioma e Normalização**: Identificação de ISO language, remoção de diacríticos/acentos e tokenização consciente de limites de palavras (*word boundaries*). | | [`test_models.py`](test_models.py) | **7** | **Modelos e Validações de Schema**: Parsing de ECP Snapshot JSON, dataclasses de nós do grafo (`RelatedEntity`) e serialização de `ClassificationResult`. | | [`test_adapters.py`](test_adapters.py) | **3** | **Interfaces de Adaptadores**: Contratos base das classes `BaseNLPAdapter`, `LocalEmbeddingsAdapter` e `LLMFallbackAdapter`. | | **TOTAL** | **247** | **100% de Aprovação (247/247 passing)** | --- ## 🚀 Como Executar os Testes ### 1. Executar Toda a Suíte do Projeto (247 testes) ```bash pytest -v ``` ### 2. Executar por Módulo Específico ```bash # Suíte Exaustiva de Classificação e Fallback (QA Sênior - 38 testes) pytest tests/test_classify_exhaustive_suite.py -v # Funil Ponta a Ponta e Integração Real com API (13 testes) pytest tests/test_e2e_text_analysis_pipeline.py -v # Testes do Adaptador de Fallback LLM Tier 3 (9 testes) pytest tests/test_llm_fallback.py -v # Conversor de Artigo para Markdown (67 testes) pytest tests/test_convert_article_to_markdown.py -v # Seletor Determinístico de Extrator (30 testes) pytest tests/test_select_article_extractor.py -v # Extrator de Conteúdo Multimotor (15 testes) pytest tests/test_extract_article_contents.py -v # Extrator de Manchetes Google News (16 testes) pytest tests/test_extract_google_news.py -v ``` --- ## 🔑 Configuração para Testes com LLM ao Vivo Para que o teste `test_funnel_live_api_execution_if_configured` e a CLI `classify.py --enable-llm` executem chamadas reais na rede, configure o arquivo `.env` na raiz do projeto: ```env OPENAI_API_KEY="sk-..." OPENAI_BASE_URL="https://omniroute.app.andreferraro.com/v1" OPENAI_MODEL="cgpt-web/gpt-5.5" ``` *(Ou utilize `GEMINI_API_KEY="..."` para utilizar a API do Google Gemini).* Se as chaves não estiverem configuradas, os testes unitários continuam executando 100% dos cenários através de mocks e stubs isolados sem quebrar o CI.