Pular para o conteúdo

Testes

Estado atual de testes e a estrategia planejada para o Douto.

Os testes serao introduzidos em tres fases ao longo dos milestones v0.3 e v0.5.

Framework: pytest Alvo: rechunk_v3.py — o componente mais complexo e fragil

Funcoes prioritarias para testar:

FuncaoLinhasPor que e critica
smart_split()~200O algoritmo de chunking em 5 passes. Nucleo de todo o pipeline.
detect_section()~20Usa 16 padroes regex para identificar a estrutura de documentos juridicos. Deteccao errada = fronteiras de chunk erradas.
classify_title()~50Distingue conteudo de ruido, bibliografia, resumo e running headers. Falsos positivos perdem conteudo real.
aggregate_footnotes()~30Agrupa notas de rodape com paragrafos-pai. Agrupamento quebrado = notas de rodape orfas.
detect_tail()~20Identifica conteudo final (bibliografia, indice). Deteccao incorreta = bibliografia misturada com conteudo.
classify_block_content()~40Classifica blocos como exemplo, tabela, caracteristicas, artigo de lei ou bibliografia.

Fixtures de teste: Amostras reais de markdown de livros juridicos (anonimizadas se necessario por questoes de propriedade intelectual).

Aceitacao minima: Pelo menos um teste por funcao acima, cobrindo tanto o caminho feliz quanto pelo menos um caso de borda.

Alvo: Funcoes compartilhadas (atualmente duplicadas, a serem extraidas para utils.py em F23)

FuncaoCasos de borda a cobrir
parse_frontmatter()Valores com dois-pontos (titulo: "Codigo Civil: Comentado"), simbolos de hash, valores multilinea, frontmatter ausente, YAML malformado
slugify()Caracteres unicode, letras acentuadas, caracteres especiais, inputs propensos a colisao (ex.: “Contratos - Vol. 1” vs. “Contratos - Vol 1”)
extract_json()JSON valido em code blocks markdown, JSON com texto extra ao redor, JSON malformado, objetos aninhados
compose_embedding_text()Campos de metadados ausentes, corpo vazio, texto muito longo (truncamento em 512 tokens)

Fase 3: Testes de Qualidade de Busca (v0.5 — F40)

Seção intitulada “Fase 3: Testes de Qualidade de Busca (v0.5 — F40)”

Alvo: Avaliacao de qualidade de busca end-to-end

ComponenteO que medir
Conjunto de avaliacao30+ queries com chunks de resultado esperados (curados manualmente)
recall@5Qual fracao dos resultados esperados aparece no top 5?
recall@10Qual fracao aparece no top 10?
nDCGOs resultados mais relevantes estao ranqueados mais alto?
Deteccao de regressaoComparacao antes/depois quando o pipeline muda (novo modelo, novo prompt, rechunking)

Esta fase tambem inclui validacao de qualidade de metadados (M06):

  • Amostrar 200 chunks aleatorios
  • Verificar instituto, tipo_conteudo, ramo contra o conteudo real
  • Estabelecer baseline de acuracia
  • Quality gate: se acuracia < 85%, parar e re-enriquecer antes de prosseguir

Funcionalidade Planejada — A infraestrutura de testes esta no roadmap para v0.3 mas ainda nao foi implementada.

Terminal window
# Run all tests
make test
# or directly:
pytest
# Run only pipeline tests
pytest tests/pipeline/
# Run a specific test
pytest -k "test_smart_split"
# Run with coverage report
pytest --cov=pipeline --cov-report=html
# Run with verbose output
pytest -v
tests/
├── conftest.py # Shared fixtures
├── fixtures/
│ ├── markdown/ # Sample legal markdown files
│ │ ├── contract_chapter.md
│ │ ├── cpc_commentary.md
│ │ └── bibliography.md
│ ├── frontmatter/ # Frontmatter edge cases
│ │ ├── valid.md
│ │ ├── colon_in_value.md
│ │ └── missing_frontmatter.md
│ └── json/ # Sample JSON responses
│ ├── enrichment_response.json
│ └── malformed_response.json
├── pipeline/
│ ├── test_rechunk_v3.py
│ ├── test_enrich_chunks.py
│ ├── test_embed_doutrina.py
│ ├── test_search_doutrina.py
│ └── test_utils.py
└── evaluation/
└── test_search_quality.py # Phase 3 eval set
ConvencaoRegra
Nomenclatura de arquivostest_{module}.py
Nomenclatura de funcoestest_{function}_{scenario}()
FixturesColocar em tests/fixtures/, usar mecanismo de fixtures do pytest
APIs externasSempre mockar. Nunca chamar MiniMax, LlamaParse ou HuggingFace em testes.
AssertionsTestar comportamento e output, nao detalhes de implementacao
IndependenciaCada teste deve ser independente — sem estado mutavel compartilhado entre testes
tests/pipeline/test_rechunk_v3.py
import pytest
from pipeline.rechunk_v3 import detect_section, classify_title
class TestDetectSection:
def test_markdown_header(self):
result = detect_section("## Responsabilidade Civil")
assert result is not None
title, ptype = result
assert ptype == "md_header"
assert "Responsabilidade Civil" in title
def test_legal_article(self):
result = detect_section("**Art. 481.** O vendedor obriga-se...")
assert result is not None
title, ptype = result
assert ptype == "artigo"
def test_plain_text_not_section(self):
result = detect_section("Este principio fundamenta a boa-fe objetiva.")
assert result is None
class TestClassifyTitle:
def test_bibliography_detection(self):
assert classify_title("REFERENCIAS BIBLIOGRAFICAS") == "bibliography"
assert classify_title("Bibliografia") == "bibliography"
def test_noise_detection(self):
assert classify_title("Agradecimentos") == "noise"
assert classify_title("PREFACIO") == "noise"
  • Usar markdown juridico real para testes de chunking (do corpus processado)
  • Anonimizar se houver questoes de propriedade intelectual — substituir nomes proprios, parafrasear conteudo preservando a estrutura
  • Usar frontmatter sintetico para testes do parser (criar casos de borda especificos)
  • Usar embeddings pequenos pre-computados para testes de busca (algumas dezenas de vetores, nao o corpus inteiro)
  • Nunca commitar dados do corpus completo nas fixtures de teste (muito grande, potenciais questoes de PI)

Cada entrada no conjunto de avaliacao deve incluir:

{
"query": "exceptio non adimpleti contractus requisitos",
"expected_chunks": ["contratos-orlando-gomes-cap12-003", "contratos-civil-cap08-001"],
"area": "contratos",
"notes": "Both chunks define the requirements for the defense"
}

Meta: pelo menos 30 queries cobrindo:

  • Diferentes dominios juridicos (civil, processual, empresarial)
  • Diferentes tipos de consulta (conceitual, artigo especifico, comparativa)
  • Casos de borda (conceitos cross-domain como “boa-fe”, termos muito especificos)