Testes
O OpenClaw tem três suítes Vitest (unit/integration, e2e, live) e um pequeno conjunto de runners Docker. Este documento é um guia de “como testamos”:- O que cada suíte cobre (e o que ela deliberadamente não cobre)
- Quais comandos executar para fluxos comuns (local, antes de push, depuração)
- Como testes live descobrem credenciais e selecionam modelos/provedores
- Como adicionar regressões para problemas reais de modelo/provedor
Início rápido
Na maioria dos dias:- Gate completo (esperado antes de push):
pnpm build && pnpm check && pnpm test - Execução local mais rápida da suíte completa em uma máquina folgada:
pnpm test:max - Loop direto de watch do Vitest (configuração moderna de projects):
pnpm test:watch - Direcionamento direto por arquivo agora também roteia caminhos de extension/channel:
pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts
- Gate de cobertura:
pnpm test:coverage - Suíte E2E:
pnpm test:e2e
- Suíte live (sondagens de modelos + ferramentas/imagens do gateway):
pnpm test:live - Direcionar silenciosamente um arquivo live:
pnpm test:live -- src/agents/models.profiles.live.test.ts
Suítes de teste (o que roda onde)
Pense nas suítes como “realismo crescente” (e instabilidade/custo crescentes):Unit / integration (padrão)
- Comando:
pnpm test - Configuração:
projectsnativos do Vitest viavitest.config.ts - Arquivos: inventários core/unit em
src/**/*.test.ts,packages/**/*.test.ts,test/**/*.test.tse os testes de nóuina allowlist cobertos porvitest.unit.config.ts - Escopo:
- Testes unitários puros
- Testes de integração in-process (autenticação do gateway, roteamento, ferramentas, parsing, configuração)
- Regressões determinísticas para bugs conhecidos
- Expectativas:
- Roda em CI
- Não requer chaves reais
- Deve ser rápido e estável
- Observação sobre projects:
pnpm test,pnpm test:watchepnpm test:changedagora usam a mesma configuração root nativa deprojectsdo Vitest.- Filtros diretos por arquivo passam nativamente pelo grafo de projects da raiz, então
pnpm test extensions/discord/src/monitor/message-handler.preflight.test.tsfunciona sem um wrapper customizado.
- Observação sobre embedded runner:
- Quando você alterar entradas de descoberta da message-tool ou o contexto de runtime da compactação, mantenha ambos os níveis de cobertura.
- Adicione regressões focadas de helpers para limites puros de roteamento/normalização.
- Também mantenha saudáveis as suítes de integração do embedded runner:
src/agents/pi-embedded-runner/compact.hooks.test.ts,src/agents/pi-embedded-runner/run.overflow-compaction.test.tsesrc/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts. - Essas suítes verificam que IDs com escopo e o comportamento de compactação ainda fluem
pelos caminhos reais
run.ts/compact.ts; testes somente de helper não são substituto suficiente para esses caminhos de integração.
- Observação sobre pool:
- A configuração base do Vitest agora usa
threadspor padrão. - A configuração compartilhada do Vitest também fixa
isolate: falsee usa o runner não isolado em root projects, e2e e live. - A lane root de UI mantém sua configuração
jsdome otimizador, mas agora também roda no runner compartilhado não isolado. pnpm testherda os mesmos padrõesthreads+isolate: falseda configuração deprojectsemvitest.config.ts.- O launcher compartilhado
scripts/run-vitest.mjsagora também adiciona--no-maglevpor padrão para processos Node filhos do Vitest para reduzir churn de compilação do V8 em grandes execuções locais. DefinaOPENCLAW_VITEST_ENABLE_MAGLEV=1se quiser comparar com o comportamento padrão do V8.
- A configuração base do Vitest agora usa
- Observação sobre iteração local rápida:
pnpm test:changedexecuta a configuração nativa de projects com--changed origin/main.pnpm test:maxepnpm test:changed:maxmantêm a mesma configuração nativa de projects, apenas com um limite maior de workers.- O autoescalonamento local de workers agora é intencionalmente conservador e também reduz quando a carga média do host já está alta, então múltiplas execuções simultâneas do Vitest causam menos dano por padrão.
- A configuração base do Vitest marca os arquivos de projects/config como
forceRerunTriggerspara que reruns em modo changed permaneçam corretos quando o wiring dos testes muda. - A configuração mantém
OPENCLAW_VITEST_FS_MODULE_CACHEativado em hosts compatíveis; definaOPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/pathse quiser um local explícito de cache para profiling direto.
- Observação sobre depuração de performance:
pnpm test:perf:importsativa relatórios de duração de import do Vitest e saída de detalhamento de import.pnpm test:perf:imports:changedlimita a mesma visão de profiling a arquivos alterados desdeorigin/main.pnpm test:perf:profile:maingrava um perfil de CPU da thread principal para a sobrecarga de startup e transform do Vitest/Vite.pnpm test:perf:profile:runnergrava perfis de CPU+heap do runner para a suíte unit com paralelismo de arquivo desativado.
E2E (gateway smoke)
- Comando:
pnpm test:e2e - Configuração:
vitest.e2e.config.ts - Arquivos:
src/**/*.e2e.test.ts,test/**/*.e2e.test.ts - Padrões de runtime:
- Usa Vitest
threadscomisolate: false, combinando com o resto do repositório. - Usa workers adaptativos (CI: até 2, local: 1 por padrão).
- Roda em modo silencioso por padrão para reduzir a sobrecarga de I/O no console.
- Usa Vitest
- Substituições úteis:
OPENCLAW_E2E_WORKERS=<n>para forçar a contagem de workers (limitada a 16).OPENCLAW_E2E_VERBOSE=1para reativar saída detalhada no console.
- Escopo:
- Comportamento end-to-end do gateway em múltiplas instâncias
- Superfícies WebSocket/HTTP, pareamento de nó e networking mais pesado
- Expectativas:
- Roda em CI (quando ativado no pipeline)
- Não requer chaves reais
- Mais partes móveis que testes unitários (pode ser mais lento)
E2E: smoke do backend OpenShell
- Comando:
pnpm test:e2e:openshell - Arquivo:
test/openshell-sandbox.e2e.test.ts - Escopo:
- Inicia um gateway OpenShell isolado no host via Docker
- Cria um sandbox a partir de um Dockerfile local temporário
- Exercita o backend OpenShell do OpenClaw via
sandbox ssh-config+ exec SSH reais - Verifica comportamento de filesystem canônico remoto por meio da ponte fs do sandbox
- Expectativas:
- Somente opt-in; não faz parte da execução padrão
pnpm test:e2e - Requer uma CLI local
openshelle um daemon Docker funcional - Usa
HOME/XDG_CONFIG_HOMEisolados, depois destrói o gateway e o sandbox de teste
- Somente opt-in; não faz parte da execução padrão
- Substituições úteis:
OPENCLAW_E2E_OPENSHELL=1para ativar o teste ao rodar manualmente a suíte e2e mais amplaOPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshellpara apontar para um binário CLI não padrão ou script wrapper
Live (provedores reais + modelos reais)
- Comando:
pnpm test:live - Configuração:
vitest.live.config.ts - Arquivos:
src/**/*.live.test.ts - Padrão: ativado por
pnpm test:live(defineOPENCLAW_LIVE_TEST=1) - Escopo:
- “Esse provedor/modelo realmente funciona hoje com credenciais reais?”
- Captura mudanças de formato do provedor, peculiaridades de chamadas de ferramenta, problemas de autenticação e comportamento de rate limit
- Expectativas:
- Não é estável em CI por design (redes reais, políticas reais de provedor, cotas, indisponibilidades)
- Custa dinheiro / usa rate limits
- Prefira executar subconjuntos limitados em vez de “tudo”
- Execuções live carregam
~/.profilepara obter chaves de API ausentes. - Por padrão, execuções live ainda isolam
HOMEe copiam material de config/auth para uma home temporária de teste para que fixtures unitários não alterem seu~/.openclawreal. - Defina
OPENCLAW_LIVE_USE_REAL_HOME=1apenas quando você intencionalmente precisar que testes live usem seu diretório home real. pnpm test:liveagora usa por padrão um modo mais silencioso: mantém a saída de progresso[live] ..., mas suprime o aviso extra de~/.profilee silencia logs de bootstrap do gateway/chatter Bonjour. DefinaOPENCLAW_LIVE_TEST_QUIET=0se quiser os logs completos de startup de volta.- Rotação de chave de API (específica por provedor): defina
*_API_KEYScom formato vírgula/ponto e vírgula ou*_API_KEY_1,*_API_KEY_2(por exemploOPENAI_API_KEYS,ANTHROPIC_API_KEYS,GEMINI_API_KEYS) ou substituição por live viaOPENCLAW_LIVE_*_KEY; testes tentam novamente em respostas de rate limit. - Saída de progresso/heartbeat:
- Suítes live agora emitem linhas de progresso em stderr para que chamadas longas a provedores mostrem atividade visível mesmo quando a captura de console do Vitest está silenciosa.
vitest.live.config.tsdesativa a interceptação de console do Vitest para que linhas de progresso de provedor/gateway sejam transmitidas imediatamente durante execuções live.- Ajuste heartbeats de modelo direto com
OPENCLAW_LIVE_HEARTBEAT_MS. - Ajuste heartbeats de gateway/probe com
OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS.
Qual suíte devo executar?
Use esta tabela de decisão:- Editando lógica/testes: execute
pnpm test(epnpm test:coveragese mudou muita coisa) - Tocando networking do gateway / protocolo WS / pareamento: adicione
pnpm test:e2e - Depurando “meu bot caiu” / falhas específicas de provedor / chamadas de ferramenta: execute um
pnpm test:liverestrito
Live: varredura de capacidades de nó Android
- Teste:
src/gateway/android-node.capabilities.live.test.ts - Script:
pnpm android:test:integration - Objetivo: invocar todos os comandos atualmente anunciados por um nó Android conectado e verificar o comportamento do contrato do comando.
- Escopo:
- Configuração manual/pré-condicionada (a suíte não instala/executa/pareia o app).
- Validação
node.invokedo gateway comando por comando para o nó Android selecionado.
- Pré-configuração obrigatória:
- App Android já conectado + pareado com o gateway.
- App mantido em primeiro plano.
- Permissões/consentimento de captura concedidos para as capacidades que você espera que passem.
- Substituições opcionais de alvo:
OPENCLAW_ANDROID_NODE_IDouOPENCLAW_ANDROID_NODE_NAME.OPENCLAW_ANDROID_GATEWAY_URL/OPENCLAW_ANDROID_GATEWAY_TOKEN/OPENCLAW_ANDROID_GATEWAY_PASSWORD.
- Detalhes completos de configuração do Android: App Android
Live: smoke de modelo (chaves de perfil)
Testes live são divididos em duas camadas para podermos isolar falhas:- “Modelo direto” nos diz se o provedor/modelo consegue responder com a chave fornecida.
- “Gateway smoke” nos diz se todo o pipeline gateway+agente funciona para esse modelo (sessões, histórico, ferramentas, política de sandbox etc.).
Camada 1: conclusão direta do modelo (sem gateway)
- Teste:
src/agents/models.profiles.live.test.ts - Objetivo:
- Enumerar modelos descobertos
- Usar
getApiKeyForModelpara selecionar modelos para os quais você tem credenciais - Executar uma pequena conclusão por modelo (e regressões direcionadas quando necessário)
- Como ativar:
pnpm test:live(ouOPENCLAW_LIVE_TEST=1se chamar o Vitest diretamente)
- Defina
OPENCLAW_LIVE_MODELS=modern(ouall, alias de modern) para realmente executar esta suíte; caso contrário ela é ignorada para manterpnpm test:livefocado no gateway smoke - Como selecionar modelos:
OPENCLAW_LIVE_MODELS=modernpara rodar a allowlist moderna (Opus/Sonnet 4.6+, GPT-5.x + Codex, Gemini 3, GLM 4.7, MiniMax M2.7, Grok 4)OPENCLAW_LIVE_MODELS=allé um alias para a allowlist moderna- ou
OPENCLAW_LIVE_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,..."(allowlist separada por vírgulas)
- Como selecionar provedores:
OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"(allowlist separada por vírgulas)
- De onde vêm as chaves:
- Por padrão: armazenamento de perfis e fallbacks de ambiente
- Defina
OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1para impor somente o armazenamento de perfis
- Por que isso existe:
- Separa “a API do provedor está quebrada / a chave é inválida” de “o pipeline do agente do gateway está quebrado”
- Contém regressões pequenas e isoladas (exemplo: replay de raciocínio + fluxos de chamada de ferramenta em OpenAI Responses/Codex Responses)
Camada 2: gateway + smoke do agente dev (o que “@openclaw” realmente faz)
- Teste:
src/gateway/gateway-models.profiles.live.test.ts - Objetivo:
- Subir um gateway in-process
- Criar/aplicar patch em uma sessão
agent:dev:*(substituição de modelo por execução) - Iterar por modelos com chaves e verificar:
- resposta “significativa” (sem ferramentas)
- uma invocação real de ferramenta funciona (sonda de leitura)
- sondas opcionais extras de ferramenta (exec+read probe)
- caminhos de regressão do OpenAI (somente chamada de ferramenta → follow-up) continuam funcionando
- Detalhes das sondas (para você conseguir explicar falhas rapidamente):
- sonda
read: o teste grava um arquivo nonce no workspace e pede ao agente para fazerreaddele e ecoar o nonce de volta. - sonda
exec+read: o teste pede ao agente para gravar um nonce viaexecem um arquivo temporário e depois lê-lo de volta. - sonda de imagem: o teste anexa um PNG gerado (gato + código aleatório) e espera que o modelo retorne
cat <CODE>. - Referência de implementação:
src/gateway/gateway-models.profiles.live.test.tsesrc/gateway/live-image-probe.ts.
- sonda
- Como ativar:
pnpm test:live(ouOPENCLAW_LIVE_TEST=1se chamar o Vitest diretamente)
- Como selecionar modelos:
- Padrão: allowlist moderna (Opus/Sonnet 4.6+, GPT-5.x + Codex, Gemini 3, GLM 4.7, MiniMax M2.7, Grok 4)
OPENCLAW_LIVE_GATEWAY_MODELS=allé um alias para a allowlist moderna- Ou defina
OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"(ou lista separada por vírgulas) para restringir
- Como selecionar provedores (evitar “tudo do OpenRouter”):
OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"(allowlist separada por vírgulas)
- Sondas de ferramenta + imagem estão sempre ativadas neste teste live:
- sonda
read+ sondaexec+read(estresse de ferramenta) - a sonda de imagem roda quando o modelo anuncia suporte a entrada de imagem
- Fluxo (alto nível):
- O teste gera um PNG minúsculo com “CAT” + código aleatório (
src/gateway/live-image-probe.ts) - Envia via
agentattachments: [{ mimeType: "image/png", content: "<base64>" }] - O gateway converte anexos em
images[](src/gateway/server-methods/agent.ts+src/gateway/chat-attachments.ts) - O agente embutido encaminha uma mensagem multimodal do usuário para o modelo
- Verificação: a resposta contém
cat+ o código (tolerância de OCR: pequenos erros são aceitos)
- O teste gera um PNG minúsculo com “CAT” + código aleatório (
- sonda
provider/model), execute:
Live: smoke de backend CLI (Claude CLI ou outras CLIs locais)
- Teste:
src/gateway/gateway-cli-backend.live.test.ts - Objetivo: validar o pipeline gateway + agente usando um backend CLI local, sem tocar na sua configuração padrão.
- Ativar:
pnpm test:live(ouOPENCLAW_LIVE_TEST=1se chamar o Vitest diretamente)OPENCLAW_LIVE_CLI_BACKEND=1
- Padrões:
- Modelo:
claude-cli/claude-sonnet-4-6 - Comando:
claude - Args:
["-p","--output-format","stream-json","--include-partial-messages","--verbose","--permission-mode","bypassPermissions"]
- Modelo:
- Substituições (opcionais):
OPENCLAW_LIVE_CLI_BACKEND_MODEL="claude-cli/claude-opus-4-6"OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.4"OPENCLAW_LIVE_CLI_BACKEND_COMMAND="/full/path/to/claude"OPENCLAW_LIVE_CLI_BACKEND_ARGS='["-p","--output-format","stream-json","--include-partial-messages","--verbose","--permission-mode","bypassPermissions"]'OPENCLAW_LIVE_CLI_BACKEND_CLEAR_ENV='["ANTHROPIC_API_KEY","ANTHROPIC_API_KEY_OLD"]'OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1para enviar um anexo de imagem real (caminhos são injetados no prompt).OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"para passar caminhos de arquivo de imagem como args da CLI em vez de injeção no prompt.OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"(ou"list") para controlar como args de imagem são passados quandoIMAGE_ARGestá definido.OPENCLAW_LIVE_CLI_BACKEND_RESUME_PROBE=1para enviar um segundo turno e validar o fluxo de retomada.
OPENCLAW_LIVE_CLI_BACKEND_DISABLE_MCP_CONFIG=0para manter a configuração MCP do Claude CLI ativada (o padrão injeta um--mcp-configvazio e estrito temporário para manter servidores MCP globais/ambientes desativados durante o smoke).
- O runner Docker fica em
scripts/test-live-cli-backend-docker.sh. - Ele executa o smoke live de backend CLI dentro da imagem Docker do repositório como o usuário não root
node, porque o Claude CLI rejeitabypassPermissionsquando invocado como root. - Para
claude-cli, ele instala o pacote Linux@anthropic-ai/claude-codeem um prefixo gravável com cache emOPENCLAW_DOCKER_CLI_TOOLS_DIR(padrão:~/.cache/openclaw/docker-cli-tools). - Para
claude-cli, o smoke live injeta uma configuração MCP vazia e estrita, a menos que você definaOPENCLAW_LIVE_CLI_BACKEND_DISABLE_MCP_CONFIG=0. - Ele copia
~/.claudepara o contêiner quando disponível, mas em máquinas onde a autenticação do Claude é baseada emANTHROPIC_API_KEY, ele também preservaANTHROPIC_API_KEY/ANTHROPIC_API_KEY_OLDpara o Claude CLI filho por meio deOPENCLAW_LIVE_CLI_BACKEND_PRESERVE_ENV.
Live: smoke de binding ACP (/acp spawn ... --bind here)
- Teste:
src/gateway/gateway-acp-bind.live.test.ts - Objetivo: validar o fluxo real de bind de conversa ACP com um agente ACP live:
- enviar
/acp spawn <agent> --bind here - vincular uma conversa sintética de canal de mensagem no lugar
- enviar um follow-up normal nessa mesma conversa
- verificar que o follow-up cai na transcrição da sessão ACP vinculada
- enviar
- Ativar:
pnpm test:live src/gateway/gateway-acp-bind.live.test.tsOPENCLAW_LIVE_ACP_BIND=1
- Padrões:
- Agente ACP:
claude - Canal sintético: contexto de conversa em estilo Slack DM
- Backend ACP:
acpx
- Agente ACP:
- Substituições:
OPENCLAW_LIVE_ACP_BIND_AGENT=claudeOPENCLAW_LIVE_ACP_BIND_AGENT=codexOPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=/full/path/to/acpx
- Observações:
- Essa lane usa a superfície
chat.senddo gateway com campos admin-only de rota de origem sintética para que testes possam anexar contexto de canal de mensagem sem fingir entrega externa. - Quando
OPENCLAW_LIVE_ACP_BIND_ACPX_COMMANDnão está definido, o teste usa o comandoacpxconfigurado/empacotado. Se a autenticação do seu harness depende de vars de ambiente de~/.profile, prefira um comandoacpxcustomizado que preserve o env do provedor.
- Essa lane usa a superfície
- O runner Docker fica em
scripts/test-live-acp-bind-docker.sh. - Ele carrega
~/.profile, copia a home de autenticação CLI correspondente (~/.claudeou~/.codex) para o contêiner, instalaacpxem um prefixo npm gravável e depois instala a CLI live solicitada (@anthropic-ai/claude-codeou@openai/codex) se estiver ausente. - Dentro do Docker, o runner define
OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpxpara que o acpx mantenha variáveis de ambiente do provedor vindas do profile carregado disponíveis para a CLI harness filha.
Receitas live recomendadas
Allowlists estreitas e explícitas são mais rápidas e menos instáveis:-
Modelo único, direto (sem gateway):
OPENCLAW_LIVE_MODELS="openai/gpt-5.4" pnpm test:live src/agents/models.profiles.live.test.ts
-
Modelo único, gateway smoke:
OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts
-
Chamada de ferramenta em vários provedores:
OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,google/gemini-3-flash-preview,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts
-
Foco em Google (chave de API Gemini + Antigravity):
- Gemini (chave de API):
OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts - Antigravity (OAuth):
OPENCLAW_LIVE_GATEWAY_MODELS="google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-pro-high" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts
- Gemini (chave de API):
google/...usa a API Gemini (chave de API).google-antigravity/...usa a ponte OAuth Antigravity (endpoint de agente estilo Cloud Code Assist).google-gemini-cli/...usa a Gemini CLI local na sua máquina (autenticação separada + peculiaridades de tooling).- Gemini API vs Gemini CLI:
- API: o OpenClaw chama a API hospedada Gemini do Google por HTTP (autenticação por chave de API / perfil); é isso que a maioria dos usuários quer dizer com “Gemini”.
- CLI: o OpenClaw executa um binário
geminilocal; ele tem sua própria autenticação e pode se comportar de forma diferente (streaming/suporte a ferramentas/incompatibilidade de versões).
Live: matriz de modelos (o que cobrimos)
Não existe uma “lista fixa de modelos de CI” (live é opt-in), mas estes são os modelos recomendados para cobrir regularmente em uma máquina de desenvolvimento com chaves.Conjunto moderno de smoke (chamada de ferramenta + imagem)
Esta é a execução de “modelos comuns” que esperamos manter funcionando:- OpenAI (não-Codex):
openai/gpt-5.4(opcional:openai/gpt-5.4-mini) - OpenAI Codex:
openai-codex/gpt-5.4 - Anthropic:
anthropic/claude-opus-4-6(ouanthropic/claude-sonnet-4-6) - Google (API Gemini):
google/gemini-3.1-pro-previewegoogle/gemini-3-flash-preview(evite modelos Gemini 2.x mais antigos) - Google (Antigravity):
google-antigravity/claude-opus-4-6-thinkingegoogle-antigravity/gemini-3-flash - Z.AI (GLM):
zai/glm-4.7 - MiniMax:
minimax/MiniMax-M2.7
OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4,openai-codex/gpt-5.4,anthropic/claude-opus-4-6,google/gemini-3.1-pro-preview,google/gemini-3-flash-preview,google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-flash,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts
Base: chamada de ferramenta (Read + Exec opcional)
Escolha pelo menos um por família de provedor:- OpenAI:
openai/gpt-5.4(ouopenai/gpt-5.4-mini) - Anthropic:
anthropic/claude-opus-4-6(ouanthropic/claude-sonnet-4-6) - Google:
google/gemini-3-flash-preview(ougoogle/gemini-3.1-pro-preview) - Z.AI (GLM):
zai/glm-4.7 - MiniMax:
minimax/MiniMax-M2.7
- xAI:
xai/grok-4(ou o mais recente disponível) - Mistral:
mistral/… (escolha um modelo compatível com “tools” que você tenha ativado) - Cerebras:
cerebras/… (se você tiver acesso) - LM Studio:
lmstudio/… (local; a chamada de ferramenta depende do modo da API)
Visão: envio de imagem (anexo → mensagem multimodal)
Inclua pelo menos um modelo compatível com imagem emOPENCLAW_LIVE_GATEWAY_MODELS (variantes compatíveis com visão de Claude/Gemini/OpenAI etc.) para exercitar a sonda de imagem.
Agregadores / gateways alternativos
Se você tiver chaves ativadas, também temos suporte a testes via:- OpenRouter:
openrouter/...(centenas de modelos; useopenclaw models scanpara encontrar candidatos compatíveis com ferramentas+imagem) - OpenCode:
opencode/...para Zen eopencode-go/...para Go (autenticação viaOPENCODE_API_KEY/OPENCODE_ZEN_API_KEY)
- Integrados:
openai,openai-codex,anthropic,google,google-vertex,google-antigravity,google-gemini-cli,zai,openrouter,opencode,opencode-go,xai,groq,cerebras,mistral,github-copilot - Via
models.providers(endpoints personalizados):minimax(cloud/API), mais qualquer proxy compatível com OpenAI/Anthropic (LM Studio, vLLM, LiteLLM etc.)
discoverModels(...) retorna na sua máquina + as chaves disponíveis.
Credenciais (nunca faça commit)
Testes live descobrem credenciais da mesma forma que a CLI. Implicações práticas:- Se a CLI funciona, testes live devem encontrar as mesmas chaves.
-
Se um teste live disser “no creds”, depure da mesma forma que faria com
openclaw models list/ seleção de modelo. -
Perfis de autenticação por agente:
~/.openclaw/agents/<agentId>/agent/auth-profiles.json(é isso que “profile keys” significa nos testes live) -
Configuração:
~/.openclaw/openclaw.json(ouOPENCLAW_CONFIG_PATH) -
Diretório de estado legado:
~/.openclaw/credentials/(copiado para a home staged live quando presente, mas não é o armazenamento principal de profile keys) -
Execuções live locais copiam por padrão a configuração ativa, arquivos
auth-profiles.jsonpor agente,credentials/legado e diretórios de autenticação de CLI externa compatíveis para uma home temporária de teste; substituições de caminhoagents.*.workspace/agentDirsão removidas nessa configuração staged para que probes fiquem longe do workspace real do host.
~/.profile), execute testes locais após source ~/.profile, ou use os runners Docker abaixo (eles podem montar ~/.profile no contêiner).
Deepgram live (transcrição de áudio)
- Teste:
src/media-understanding/providers/deepgram/audio.live.test.ts - Ativar:
DEEPGRAM_API_KEY=... DEEPGRAM_LIVE_TEST=1 pnpm test:live src/media-understanding/providers/deepgram/audio.live.test.ts
BytePlus coding plan live
- Teste:
src/agents/byteplus.live.test.ts - Ativar:
BYTEPLUS_API_KEY=... BYTEPLUS_LIVE_TEST=1 pnpm test:live src/agents/byteplus.live.test.ts - Substituição opcional de modelo:
BYTEPLUS_CODING_MODEL=ark-code-latest
Geração de imagem live
- Teste:
src/image-generation/runtime.live.test.ts - Comando:
pnpm test:live src/image-generation/runtime.live.test.ts - Escopo:
- Enumera todos os plugins registrados de provedores de geração de imagem
- Carrega variáveis de ambiente ausentes de provedores a partir do seu shell de login (
~/.profile) antes de sondar - Usa por padrão chaves de API live/env antes de perfis de autenticação armazenados, para que chaves de teste obsoletas em
auth-profiles.jsonnão mascarem credenciais reais do shell - Ignora provedores sem autenticação/perfil/modelo utilizável
- Executa as variantes padrão de geração de imagem pela capacidade compartilhada de runtime:
google:flash-generategoogle:pro-generategoogle:pro-editopenai:default-generate
- Provedores empacotados atualmente cobertos:
openaigoogle
- Restrição opcional:
OPENCLAW_LIVE_IMAGE_GENERATION_PROVIDERS="openai,google"OPENCLAW_LIVE_IMAGE_GENERATION_MODELS="openai/gpt-image-1,google/gemini-3.1-flash-image-preview"OPENCLAW_LIVE_IMAGE_GENERATION_CASES="google:flash-generate,google:pro-edit"
- Comportamento opcional de autenticação:
OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1para forçar autenticação pelo armazenamento de perfis e ignorar substituições somente de ambiente
Runners Docker (verificações opcionais “funciona em Linux”)
Esses runners Docker se dividem em dois grupos:- Runners live-model:
test:docker:live-modelsetest:docker:live-gatewayexecutam apenas seu arquivo live correspondente de profile-key dentro da imagem Docker do repositório (src/agents/models.profiles.live.test.tsesrc/gateway/gateway-models.profiles.live.test.ts), montando seu diretório local de configuração e workspace (e carregando~/.profilese montado). Os entrypoints locais correspondentes sãotest:live:models-profilesetest:live:gateway-profiles. - Runners Docker live usam por padrão um limite menor de smoke para manter viável uma varredura Docker completa:
test:docker:live-modelsusa por padrãoOPENCLAW_LIVE_MAX_MODELS=12, etest:docker:live-gatewayusa por padrãoOPENCLAW_LIVE_GATEWAY_SMOKE=1,OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8,OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000eOPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000. Substitua essas variáveis quando você quiser explicitamente a varredura maior e exaustiva. test:docker:allconstrói a imagem Docker live uma vez viatest:docker:live-build, depois a reutiliza nas duas lanes Docker live.- Runners smoke de contêiner:
test:docker:openwebui,test:docker:onboard,test:docker:gateway-network,test:docker:mcp-channelsetest:docker:pluginsiniciam um ou mais contêineres reais e verificam caminhos de integração de nível mais alto.
- Modelos diretos:
pnpm test:docker:live-models(script:scripts/test-live-models-docker.sh) - ACP bind smoke:
pnpm test:docker:live-acp-bind(script:scripts/test-live-acp-bind-docker.sh) - CLI backend smoke:
pnpm test:docker:live-cli-backend(script:scripts/test-live-cli-backend-docker.sh) - Gateway + agente dev:
pnpm test:docker:live-gateway(script:scripts/test-live-gateway-models-docker.sh) - Open WebUI live smoke:
pnpm test:docker:openwebui(script:scripts/e2e/openwebui-docker.sh) - Assistente de onboarding (TTY, scaffolding completo):
pnpm test:docker:onboard(script:scripts/e2e/onboard-docker.sh) - Networking do gateway (dois contêineres, autenticação WS + health):
pnpm test:docker:gateway-network(script:scripts/e2e/gateway-network-docker.sh) - Ponte de canal MCP (Gateway seeded + ponte stdio + smoke bruto de frame de notificação do Claude):
pnpm test:docker:mcp-channels(script:scripts/e2e/mcp-channels-docker.sh) - Plugins (smoke de instalação + alias
/plugin+ semântica de reinício de bundle Claude):pnpm test:docker:plugins(script:scripts/e2e/plugins-docker.sh)
OPENCLAW_SKIP_CHANNELS=1 para que probes live do gateway não iniciem
workers reais de canais Telegram/Discord/etc. dentro do contêiner.
test:docker:live-models ainda executa pnpm test:live, então passe também
OPENCLAW_LIVE_GATEWAY_* quando precisar restringir ou excluir cobertura live
de gateway dessa lane Docker.
test:docker:openwebui é um smoke de compatibilidade de nível mais alto: ele inicia um
contêiner de gateway OpenClaw com endpoints HTTP compatíveis com OpenAI ativados,
inicia um contêiner Open WebUI fixado apontando para esse gateway, faz login pelo
Open WebUI, verifica que /api/models expõe openclaw/default, depois envia uma
solicitação real de chat pelo proxy /api/chat/completions do Open WebUI.
A primeira execução pode ser visivelmente mais lenta porque o Docker pode precisar baixar a
imagem do Open WebUI e o Open WebUI pode precisar concluir sua própria configuração inicial.
Essa lane espera uma chave de modelo live utilizável, e OPENCLAW_PROFILE_FILE
(~/.profile por padrão) é a forma principal de fornecê-la em execuções Dockerizadas.
Execuções bem-sucedidas imprimem um pequeno payload JSON como { "ok": true, "model": "openclaw/default", ... }.
test:docker:mcp-channels é intencionalmente determinístico e não precisa de uma
conta real de Telegram, Discord ou iMessage. Ele inicia um contêiner Gateway seeded,
inicia um segundo contêiner que executa openclaw mcp serve e depois
verifica descoberta de conversa roteada, leituras de transcrição, metadados de anexos,
comportamento da fila de eventos live, roteamento de envio de saída e notificações em estilo Claude de canal +
permissão pela ponte MCP stdio real. A verificação de notificação
inspeciona diretamente os frames MCP stdio brutos, então o smoke valida o que a
ponte realmente emite, não apenas o que um SDK específico de cliente por acaso expõe.
Smoke manual de thread ACP em linguagem simples (não CI):
bun scripts/dev/discord-acp-plain-language-smoke.ts --channel <discord-channel-id> ...- Mantenha esse script para fluxos de regressão/depuração. Ele pode ser necessário novamente para validação de roteamento de thread ACP, então não o exclua.
OPENCLAW_CONFIG_DIR=...(padrão:~/.openclaw) montado em/home/node/.openclawOPENCLAW_WORKSPACE_DIR=...(padrão:~/.openclaw/workspace) montado em/home/node/.openclaw/workspaceOPENCLAW_PROFILE_FILE=...(padrão:~/.profile) montado em/home/node/.profilee carregado antes de rodar os testesOPENCLAW_DOCKER_CLI_TOOLS_DIR=...(padrão:~/.cache/openclaw/docker-cli-tools) montado em/home/node/.npm-globalpara instalações CLI em cache dentro do Docker- Diretórios de autenticação de CLI externa sob
$HOMEsão montados como somente leitura em/host-auth/..., depois copiados para/home/node/...antes do início dos testes- Padrão: monta todos os diretórios compatíveis (
.codex,.claude,.minimax) - Execuções restritas por provedor montam apenas os diretórios necessários inferidos de
OPENCLAW_LIVE_PROVIDERS/OPENCLAW_LIVE_GATEWAY_PROVIDERS - Substitua manualmente com
OPENCLAW_DOCKER_AUTH_DIRS=all,OPENCLAW_DOCKER_AUTH_DIRS=noneou uma lista separada por vírgulas, comoOPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex
- Padrão: monta todos os diretórios compatíveis (
OPENCLAW_LIVE_GATEWAY_MODELS=.../OPENCLAW_LIVE_MODELS=...para restringir a execuçãoOPENCLAW_LIVE_GATEWAY_PROVIDERS=.../OPENCLAW_LIVE_PROVIDERS=...para filtrar provedores dentro do contêinerOPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1para garantir que credenciais venham do armazenamento de perfis (não do ambiente)OPENCLAW_OPENWEBUI_MODEL=...para escolher o modelo exposto pelo gateway para o smoke do Open WebUIOPENCLAW_OPENWEBUI_PROMPT=...para substituir o prompt de verificação de nonce usado pelo smoke do Open WebUIOPENWEBUI_IMAGE=...para substituir a tag fixada da imagem do Open WebUI
Verificação básica de docs
Execute verificações de docs após edições em documentação:pnpm check:docs.
Execute a validação completa de âncoras do Mintlify quando também precisar de verificações de heading na própria página: pnpm docs:check-links:anchors.
Regressão offline (segura para CI)
Estas são regressões de “pipeline real” sem provedores reais:- Chamada de ferramenta do gateway (OpenAI mockado, gateway real + loop do agente):
src/gateway/gateway.test.ts(caso: “runs a mock OpenAI tool call end-to-end via gateway agent loop”) - Assistente do gateway (WS
wizard.start/wizard.next, grava config + auth aplicada):src/gateway/gateway.test.ts(caso: “runs wizard over ws and writes auth token config”)
Evals de confiabilidade do agente (Skills)
Já temos alguns testes seguros para CI que se comportam como “evals de confiabilidade do agente”:- Chamada de ferramenta mockada pelo gateway real + loop do agente (
src/gateway/gateway.test.ts). - Fluxos end-to-end do assistente que validam wiring de sessão e efeitos de configuração (
src/gateway/gateway.test.ts).
- Tomada de decisão: quando Skills estão listadas no prompt, o agente escolhe a Skill certa (ou evita as irrelevantes)?
- Conformidade: o agente lê
SKILL.mdantes de usar e segue etapas/args obrigatórios? - Contratos de fluxo: cenários de múltiplos turnos que verificam ordem de ferramentas, continuidade do histórico de sessão e limites de sandbox.
- Um scenario runner usando provedores mockados para verificar chamadas de ferramenta + ordem, leituras de arquivo de Skill e wiring de sessão.
- Uma pequena suíte de cenários focados em Skill (usar vs evitar, bloqueio, injeção de prompt).
- Evals live opcionais (opt-in, controladas por env) somente depois que a suíte segura para CI estiver pronta.
Testes de contrato (forma de plugin e canal)
Testes de contrato verificam se todo plugin e canal registrado está em conformidade com seu contrato de interface. Eles iteram por todos os plugins descobertos e executam uma suíte de verificações de forma e comportamento. A lane unit padrão depnpm test intencionalmente
ignora esses arquivos compartilhados de seam e smoke; execute os comandos de contrato explicitamente
quando mexer em superfícies compartilhadas de canal ou provedor.
Comandos
- Todos os contratos:
pnpm test:contracts - Apenas contratos de canal:
pnpm test:contracts:channels - Apenas contratos de provedor:
pnpm test:contracts:plugins
Contratos de canal
Localizados emsrc/channels/plugins/contracts/*.contract.test.ts:
- plugin - Forma básica do plugin (id, nome, capabilities)
- setup - Contrato do assistente de configuração
- session-binding - Comportamento de binding de sessão
- outbound-payload - Estrutura do payload de mensagem
- inbound - Tratamento de mensagem recebida
- actions - Handlers de ação do canal
- threading - Tratamento de ID de thread
- directory - API de diretório/lista
- group-policy - Aplicação de política de grupo
Contratos de status de provedor
Localizados emsrc/plugins/contracts/*.contract.test.ts.
- status - Sondas de status de canal
- registry - Forma do registro de plugins
Contratos de provedor
Localizados emsrc/plugins/contracts/*.contract.test.ts:
- auth - Contrato do fluxo de autenticação
- auth-choice - Escolha/seleção de autenticação
- catalog - API de catálogo de modelos
- discovery - Descoberta de plugin
- loader - Carregamento de plugin
- runtime - Runtime de provedor
- shape - Forma/interface do plugin
- wizard - Assistente de configuração
Quando executar
- Após alterar exports ou subpaths do plugin-sdk
- Após adicionar ou modificar um plugin de canal ou provedor
- Após refatorar registro ou descoberta de plugin
Adicionando regressões (orientação)
Quando você corrige um problema de provedor/modelo descoberto em live:- Adicione uma regressão segura para CI se possível (provedor mockado/stubado ou capture a transformação exata do formato da solicitação)
- Se for inerentemente live-only (rate limits, políticas de autenticação), mantenha o teste live restrito e opt-in por variáveis de ambiente
- Prefira mirar a menor camada que captura o bug:
- bug de conversão/replay de solicitação do provedor → teste de modelos diretos
- bug no pipeline de sessão/histórico/ferramenta do gateway → gateway live smoke ou teste mockado do gateway seguro para CI
- Guardrail de travessia de SecretRef:
src/secrets/exec-secret-ref-id-parity.test.tsderiva um alvo amostrado por classe de SecretRef a partir de metadados do registro (listSecretTargetRegistryEntries()), depois verifica se IDs exec de segmento de travessia são rejeitados.- Se você adicionar uma nova família de alvo SecretRef
includeInPlanemsrc/secrets/target-registry-data.ts, atualizeclassifyTargetClassnesse teste. O teste falha intencionalmente em IDs de alvo não classificados para que novas classes não possam ser ignoradas silenciosamente.