Repository navigation
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.
pip install pytest pytest-covTodas as outras dependências são as mesmas do Codis (requirements.txt).
# 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/ -qLista 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.pyetest_chat_ws_adapters.py(11 casos) só rodam comwebsocketsinstalado; sem ele, o pytest coleta 1.672 casos.
Medição de referência (
pytest --cov), não regenerada automaticamente - rodepytest tests/ --cov=srcpara 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.
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.
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
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.
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
|
-
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.MagicMockapenas 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 quetest_edge_case_1. - threading.Event para sincronizar testes assíncronos com timeout explícito.
- Crie
tests/test_seu_modulo.py - Importe o stub de Tkinter via
conftest.pyautomaticamente (não precisa fazer nada) - Use as fixtures disponíveis para isolamento
- Agrupe casos em classes por funcionalidade
- 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.
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çõesrun_*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.
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.
-
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) ewsgidav+cheroot(WebDAV). São pulados se as bibliotecas não estiverem instaladas (pip install pyftpdlib wsgidav cheroot). - SSH real é opcional: com um
sshdlocal de teste, exporteCODIS_TEST_SSH="127.0.0.1:2222:usuario:senha"(a pasta~/projdo usuário precisa tera.txt,2024edir 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).
Começando
Editando
- Editor
- Inteligência do Editor
- KDocs
- Linting & LSP
- Debug
- Git
- Terminal
- Workspace & Produtividade
- Utilitários de Desenvolvimento
Assistente e conectividade
Ferramentas e extras
- Recursos Avançados
- Recursos Exclusivos
- K-UI
- Sistema & Performance
- Backups, Lixeira & Arquivos
- Painel de Saída
- Acessibilidade
- Editor de Imagens (Paint)
- Utilitários Pessoais
- Incorporar Programas e Preview Web
- DOOM Embutido
Para quem desenvolve
Projeto