| English | Português (Brasil) |
Execute a suíte completa com:
python -m unittest discover -s tests -v
Ou use:
make test
O teste de integração monta e realiza o link da ROM, validando em seguida seu cabeçalho,
mapper, bancos, vetores, dados de CHR, tamanho final, configuração de linker gerada
e mapa de memória da CPU. Testes focados no layout de memória cobrem limites físicos,
regiões reservadas, alocação determinística, esgotamento obrigatório de temporários,
fallback opcional de promoção, configurações internas malformadas e capacidade
de segmentos. Um teste de listagem do ca65 verifica opcodes de Zero Page para símbolos
promovidos e estado de runtime da NMI, além de opcodes absolutos para armazenamento
de fallback. Testes estruturais de backend verificam a preservação de registradores,
o laço de espera autoritativo baseado em contador, detecção persistente de quadros
pendentes, inicialização de renderização condicionada a VBlank e a separação de chamadas
de atualização na thread principal do callback restrito da NMI.
Testes de controle verificam a ordem serial dos bits, estados atual e anterior independentes,
argumentos em tempo de compilação, mascaramento de transição, uma leitura protegida por
quadro processado, opcodes de Zero Page, preparação de sprite fixo, setters gerais de sprites,
preservação de atributos, estado de visibilidade, inicialização e DMA de OAM e Assembly
determinístico. Testes de gerenciamento de sprites cobrem adicionalmente a posse estática
de OAM, coexistência com índices explícitos, esgotamento de 64 entradas e o setter
de posição combinada. Testes de metasprites validam o asset fornecido pelo PNG2CHR Studio,
seu contrato de deslocamento já relativo à âncora, variantes malformadas de esquema,
layouts arbitrários com sinal/esparsos/reutilizados, pivôs centralizados e não centralizados,
geometria horizontal/vertical assimétrica, preservação de limites delimitadores,
XOR de flip de componentes, posse compartilhada e esgotamento de OAM, tabelas compactas em PRG,
RAM por instância, visibilidade, ocultação em quadros mais curtos, estrutura de recorte de borda
e comportamento opcional no Mesen. Testes de animação de sprites adicionam importação simbólica
de sequências, durações padrão e sobrescritas, política de repetição (loop), conclusão de disparo
único (one-shot), estabilidade na mesma animação, reinício, avanço oculto, preservação de flip,
instâncias independentes, contagens variáveis de componentes, emissão de recursos e custos exatos
de tabelas em RAM/PRG.
Testes do toolchain são ignorados com uma mensagem explícita quando o ca65 ou ld65
não estiver disponível.
Para incluir o teste opcional de comportamento no Mesen sem interface gráfica (headless), aponte
MESEN_PATH para o executável do emulador ou para o diretório que o contém antes de executar a suíte.
O teste compila os exemplos de comportamento, executa suas ROMs e verifica variáveis finais,
armazenamento de parâmetros de procedimento, endereços em RAM comum e promovidos quando
aplicável, progresso do contador de NMI, três iterações distintas de nes.wait_frame,
progresso dos callbacks de atualização e VBlank ao longo do estouro circular de 8 bits do contador
de quadros, comportamento de quadros pendentes em atualizações lentas sem chamadas aninhadas e a cor
de fundo universal. A ROM de controle também aciona ambas as portas virtuais, verifica o comportamento
de cada direção e botão, verifica a consistência da OAM e executa ao longo do estouro circular do
contador de quadros de 8 bits. A ROM de sprites verifica um sprite visível, 63 entradas ocultas,
composição de atributos e seleção de página de DMA. A ROM do jogador metasprite aciona todas as oito
direções do D-pad e valida inversão (flip) centralizada no local, seleção manual de quadro enquanto
invertido, composição de flip de origem/total, limites de jogabilidade totalmente visíveis derivados
do asset em todas as quatro bordas, estado de ocultar/mover/exibir, conversão lógica de Y, OAM de
componentes e DMA. Um cenário de teste (fixture) determinístico separado de recorte valida todas as
quatro bordas, flips horizontal, vertical e combinado, deslocamentos negativos, coordenadas sem
estouro circular, movimentação oculta e troca de quadro invertido; o exemplo de recorte voltado ao
usuário permanece deliberadamente lento o suficiente para inspeção visual. O fixture de animação de
sprites valida adicionalmente a temporização exata de 2/3/1 quadros, reinício de loop, retenção e
conclusão de quadro final em disparo único, reinício explícito, reprodução oculta, tempos de início
independentes, ocultação de slots obsoletos, persistência de flip, cancelamento de quadro manual e
isolamento de instâncias inativas. A regressão do jogador consolidado verifica que consumidores
manuais e animados emitem geometria de quadro centralizada idêntica, que seleções de idle/movimento
não reiniciam quando repetidas e que a orientação sobrevive a mudanças de estado. Uma segunda passagem
no Mesen executa o exemplo real de jogador animado em idle, movimento para a esquerda, idle voltado
para a esquerda, movimento vertical, movimento para a direita e idle voltado para a direita. O exemplo
visual de recorte também completa um ciclo inteiro centro/borda parcial sob uma verificação
automatizada de estado/OAM:
$env:MESEN_PATH = "C:\path\to\Mesen.exe"
python -m unittest discover -s tests -v
O teste de comportamento é claramente ignorado quando o Mesen ou a cadeia de ferramentas cc65 não estiver disponível.
O repositório utiliza o GitHub Actions para testes de regressão automatizados a
cada push e execução manual (workflow_dispatch). Todos os jobs de CI são
executados em executores pinados no ubuntu-24.04. A esteira é composta por
três jobs:
compiler-toolchain: Configura o Python e o toolchain cc65 (ca65 e
ld65), executa a suíte completa de regressão do compilador (lexer,
parser, análise semântica, layout de memória, diagnósticos, golden assembly e
testes de integração de build de ROM) e gera o relatório de benchmarks do
compilador através de tools/measure_benchmarks.py. O relatório gerado é
publicado diretamente no resumo da execução do job e exportado como o artefato
benchmark-report. As métricas de benchmark são atualmente observáveis e
informativas, sem critérios de bloqueio por threshold.mesen-runtime: Depende do compiler-toolchain, instala ca65/ld65 e
o MesenCE 2.2.1, configura MESEN_PATH e executa a suíte completa de testes
de comportamento em runtime no Mesen headless.ci-gate: Atua como o check autoritativo que valida se tanto
compiler-toolchain quanto mesen-runtime foram concluídos com sucesso.Durante o desenvolvimento, itere utilizando testes focados no subsistema que está sendo
modificado. Enquanto os testes de integração locais toleram a ausência de dependências
externas (ca65, ld65 ou Mesen) com skips informativos, os jobs autoritativos no CI
devem obrigatoriamente instalar todas as dependências requeridas e executar todas as
asserções sem pular validações.
O repositório fornece alvos canônicos no Makefile que encapsulam os pontos de entrada padrão do Python:
| Alvo | Comando | Requisitos | Descrição |
|---|---|---|---|
make test |
python -m unittest discover -s tests -v |
Python | Suíte padrão de testes de regressão local. Pula testes do Mesen quando MESEN_PATH não está definido. |
make test-all |
make test |
Python | Alias explícito de make test executando a suíte completa de descoberta. |
make test-mesen |
python -m unittest tests.test_integration.MesenIntegrationTests -v |
ca65, ld65, MESEN_PATH |
Executa a suíte de testes de emulação de comportamento no Mesen headless. |
make benchmark |
python tools/measure_benchmarks.py |
ca65, ld65 |
Executa a ferramenta de medição de recursos e padrões do compilador. |
make rom |
python -m nes_pascal.cli examples/minimal.nsp -o build/minimal.nes |
ca65, ld65 |
Compila a ROM mínima representativa canônica. |
make clean |
Remove build/, *.log, benchmark-report.md |
Python | Limpa com segurança saídas temporárias de build sem remover assets versionados. |
make validate |
Executa test-all, benchmark, rom |
ca65, ld65 |
Validação local abrangente pré-push. Não substitui o gate autoritativo do CI. |
Para executar comandos equivalentes diretamente sem o Make:
# Executar testes unitários focados durante o desenvolvimento (ex.: arrays)
python -m unittest tests.test_arrays -v
# Executar a suíte padrão de regressão do compilador
python -m unittest discover -s tests -v
# Executar a suíte de testes de runtime no Mesen (requer ca65, ld65 e MESEN_PATH)
python -m unittest tests.test_integration.MesenIntegrationTests -v
# Gerar o relatório de métricas de benchmark localmente (requer ca65 e ld65 no PATH)
python tools/measure_benchmarks.py
# Compilar a ROM mínima representativa
python -m nes_pascal.cli examples/minimal.nsp -o build/minimal.nes