Skip to content
github-actions[bot] edited this page Nov 13, 2026 · 1 revision

🧪 Testes

O Codis possui uma suíte de testes automatizados projetada para rodar completamente headless (sem display gráfico), permitindo que todo o CI/CD execute em runners Linux sem configuração especial. 1.683 casos em 70 arquivos cobrem os subsistemas mais críticos - eventos, transformações de texto, IA, sintaxe das 25 linguagens, LSP, providers, plugins, diff, atualizador, chat, terminal e roteamento standalone.


Executar os Testes

Instalação

pip install pytest pytest-cov

Todas as outras dependências são as mesmas do Codis (requirements.txt).

Comandos

# Todos os testes
pytest tests/

# Com relatório de cobertura no terminal
pytest tests/ --cov=src --cov-report=term-missing

# Com cobertura em HTML (abre em browser)
pytest tests/ --cov=src --cov-report=html
open htmlcov/index.html

# Arquivo específico
pytest tests/test_syntax_patterns.py -v

# Módulo específico por palavra-chave
pytest tests/ -k "TestDiffEngine"

# Parar no primeiro falho
pytest tests/ -x

# Ignorar testes de providers (mais rápido, sem I/O de rede simulado)
pytest tests/ --ignore=tests/test_ia_providers.py

# Saída mínima (apenas erros)
pytest tests/ -q

Inventário por Arquivo

Lista tirada da coleta do pytest. A coluna de módulos mostra os src.* que cada arquivo importa.

Arquivo de teste Módulos exercitados Casos
test_syntax_patterns.py src.syntax.patterns 92
test_updater.py src.updater, src.updater.backup, src.updater.result 87
test_text_transforms.py src.editor.text_transforms 79
test_collab_ot.py src.collab.ot 56
test_events_bus.py src.events, src.events.bus, src.events.kinds 54
test_snippets.py src.editor.snippets 50
test_paint_engine.py src.ui 49
test_constants.py src.constants 48
test_kui_colors.py src.ui.k_ui._colors 46
test_suggest.py src.editor 46
test_plugins.py src.constants, src.plugins.api 45
test_theme_utils.py src.theme.utils 43
test_events_pipeline_correlator_window.py src.events.bus, src.events.correlator, src.events.kinds 41
test_remote_adapters.py src.ui 40
test_ia_providers.py src.ia.providers 38
test_approval_gate.py src.ia.approval_gate 37
test_lsp_protocol.py src.lsp.protocol 37
test_terminal_keys.py src.terminal.keys 37
test_standalone.py src.standalone 35
test_kui_world.py src.ui.k_ui._world 30
test_i18n.py src.i18n 28
test_kui_engine.py src.ui.k_ui._colors, src.ui.k_ui._perf, src.ui.k_ui._engine 28
test_pyexec.py src.terminal.backends, src.lsp 28
test_events_stream.py src.events.bus, src.events.kinds 27
test_doom_embed.py src.ui 26
test_theme_preview_panel.py src.theme.base 25
test_terminal_vt.py src.terminal.palette, src.terminal.vt 24
test_config.py src.constants, src.config 23
test_calculator_safe_eval.py src.ui.calculator_panel 22
test_diff_engine.py src.diff.engine 22
test_theme.py src.theme.base, src.theme.manager 21
test_trash_core.py - 21
test_ia_context_builder.py src.ia.context_builder 19
test_ia_pair.py src.ia, src.ia.toolbox 18
test_lint_diag.py src.lint.manager 18
test_wizard_options.py src.theme.base, src.constants 18
test_toolbox_security.py src.ia.toolbox 17
test_kui_perf.py src.ui.k_ui._perf 16
test_collab_net.py src.collab.net, src.collab.ot, src.collab.session 15
test_ia_session.py src.ia 15
test_terminal_session.py src.terminal.backends, src.terminal.session 15
test_ia_checkpoints.py src.ia.checkpoints, src.ia 14
test_menu_bar_switching.py src.ui 14
test_utils_and_sync.py src.editor._pane_utils 14
test_sql_studio_helpers.py src.ui.sql_studio 13
test_toolbox_checkpoints.py src.ia.toolbox 13
test_zen_audio.py src.ui 13
test_terminal_renderer.py src.terminal.backends, src.terminal.session, src.terminal.view 12
test_collab_security.py src.ui.collab_panel 11
test_exit_save.py - 11
test_terminal_panel_logic.py src.ui.terminal 11
test_terminal_shells.py src.terminal.shells 11
test_webdev.py src.ui 11
test_chat_irc.py src.chat.adapters.irc, src.chat.models, src.chat.session 10
test_kui_bgrenderer.py src.ui.k_ui._bgrenderer, src.ui.k_ui._perf 10
test_persistence_utils.py src.ui._persistence_utils 10
test_app_embed.py src.ui 7
test_chat_ws_adapters.py src.chat.models, src.chat.session, src.chat.adapters.slack 6
test_ia_provider_races.py src.ia 6
test_task_manager_helpers.py src.ui.task_manager 6
test_workspace_trust_enforcement.py src.ia.toolbox 6
test_chat_mqtt_ws.py src.chat.adapters, src.chat.models, src.chat.session 5
test_font_safety.py - 5
test_chat_http_adapters.py src.chat.models, src.chat.session 4
test_chat_render.py src.ui.chat_render 4
test_chat_xmpp.py src.chat.models, src.chat.session 4
test_diag_hover_throttle.py src.editor 4
test_ia_skills.py src.ia.actions 4
test_lsp_shutdown.py src.lsp, src.lsp.client 4
test_stall_trace.py src.stall_trace 4
Total (70 arquivos) 1.683

Os 191 testes de tests_gui/ (18 arquivos) exigem display real e não entram no total acima. test_chat_mqtt_ws.py e test_chat_ws_adapters.py (11 casos) só rodam com websockets instalado; sem ele, o pytest coleta 1.672 casos.


Cobertura por Subsistema

Medição de referência (pytest --cov), não regenerada automaticamente - rode pytest tests/ --cov=src para valores atuais.

Subsistema Stmts Cobertos Cobertura
events/ 971 917 94%
diff/ 101 95 94%
theme/ 559 455 81%
lsp/ 1 458 429 29%
ia/ 3 283 441 13%
plugins/ 1 955 294 15%
lint/ 539 116 21%
syntax/ 476 43 9%
core (config, i18n, standalone…) 5 506 374 7%
editor/ 10 234 189 2%
ui/ 33 244 691 2%
TOTAL 58 326 4 044 6,9%

Por que a cobertura global é baixa? O projeto tem ~50 000 statements de código UI/Tkinter que só executam com display gráfico real. A cobertura dos módulos de lógica pura - events (94%), diff (94%), theme (81%), LSP, IA, plugins - é significativamente maior e reflete a qualidade real da suíte headless.


Como a Suíte Funciona

Headless sem display gráfico

O conftest.py instala um stub completo de Tkinter antes de qualquer importação do projeto. Isso permite que todos os módulos com import tkinter carreguem normalmente em runners CI sem display (sem $DISPLAY nem Xvfb).

O stub cobre: tkinter, tkinter.ttk, tkinter.font, tkinter.filedialog, tkinter.messagebox, tkinter.simpledialog e tkinter.colorchooser.

O stub _W (widget base) salva todos os kwargs recebidos em __init__ e os retorna corretamente via cget(), permitindo testar widgets como Chip, Toast e ProgressBar sem display.

Isolamento de configuração

A fixture isolated_config_dir (com autouse=True) redireciona CONFIG_DIR e CONFIG_FILE para um diretório temporário único por teste. Isso garante que:

  • Os testes nunca leem nem escrevem na configuração real do usuário (~/.codis/)
  • Cada teste começa com estado limpo
  • Testes paralelos não interferem entre si

Sem dependências de rede

Testes de provedores de IA verificam apenas comportamento de erro, cancelamento e configuração - sem fazer chamadas reais para Anthropic, OpenAI, Google ou Ollama. Testes de LSP verificam apenas a estrutura das mensagens JSON-RPC, não se comunicam com servers reais.


Fixtures Disponíveis

Documentadas em conftest.py, disponíveis em todos os arquivos de teste via injeção do pytest:

Fixture Escopo O que provê
cfg function Instância limpa de ConfigManager em diretório temporário
tmp_py_file function Arquivo .py temporário com código Python de exemplo
tmp_js_file function Arquivo .js temporário com código JavaScript de exemplo
mock_workspace function Pasta temporária com main.py, utils.py, requirements.txt e README.md

Convenções de Código de Teste

  • Classes de teste agrupam casos relacionados: class TestGetSet, class TestPersistence.
  • Fixtures de escopo de função garantem isolamento total entre testes.
  • Mocks mínimos - unittest.mock.MagicMock apenas quando necessário, preferindo testar a lógica real.
  • Mensagens de asserção em português, consistentes com o padrão do projeto.
  • Nomes descritivos: test_diff_empty_strings_returns_empty_hunks é melhor que test_edge_case_1.
  • threading.Event para sincronizar testes assíncronos com timeout explícito.

Adicionar Novos Testes

  1. Crie tests/test_seu_modulo.py
  2. Importe o stub de Tkinter via conftest.py automaticamente (não precisa fazer nada)
  3. Use as fixtures disponíveis para isolamento
  4. Agrupe casos em classes por funcionalidade
  5. Execute localmente: pytest tests/test_seu_modulo.py -v

Pull requests que adicionam features devem incluir testes cobrindo o caminho feliz e pelo menos um caso de erro esperado.


Áreas Sem Cobertura Atual

As seguintes áreas ainda não têm testes automatizados e são alvo do roadmap:

  • src/ui/ - painéis e widgets de UI (exceto K-UI e alguns painéis como calculadora e embed)
  • src/ia/iaspace.py - UI do painel de IA
  • src/ia/toolbox.py - execução das 40 ferramentas (requer mocks de I/O complexos)
  • src/standalone.py - funções run_* individuais (abrem janelas Tkinter)
  • Testes de integração (múltiplos subsistemas juntos)
  • Testes de performance (tempo de carregamento, uso de memória)

Contribuições de testes para essas áreas são especialmente bem-vindas. Veja CONTRIBUTING.md para o fluxo de pull request.


CI/CD

A suíte roda automaticamente no GitHub Actions (job quality do pipeline.yml) a cada push e pull request que mude código, em paralelo ao build. Veja wiki/builds.md para detalhes dos workflows.

pytest tests/ --cov=src --cov-report=xml --junit-xml=test-results.xml

O CI falha se qualquer teste falhar - isso é intencional. Relatórios de cobertura são publicados como artefatos de cada run para acompanhamento de tendência ao longo do tempo.


Testes do Navegador Remoto e da escala da interface

  • tests/test_remote_adapters.py - parsers puros (ls, LIST Unix/IIS, índices Apache/nginx, URLs) e protocolos contra servidores reais levantados em threads: http.server, pyftpdlib (FTP) e wsgidav+cheroot (WebDAV). São pulados se as bibliotecas não estiverem instaladas (pip install pyftpdlib wsgidav cheroot).
  • SSH real é opcional: com um sshd local de teste, exporte CODIS_TEST_SSH="127.0.0.1:2222:usuario:senha" (a pasta ~/proj do usuário precisa ter a.txt, 2024 e dir with space/) antes de rodar o pytest.
  • tests_gui/test_remote_browser_panel.py - painel com servidor em memória (respostas fora de ordem, conflito, falha de upload, sync ao salvar) e um teste ponta a ponta com FTP real.
  • tests_gui/test_ui_scale.py - escala da interface (sem acúmulo, widgets novos, barras fixas, Treeview).

Clone this wiki locally