Communityn8ngithub.com

ashtonfeliciano/n8n-evaluations-runner

Crie e execute suítes de testes lógicos sem custos de API para fluxos de trabalho n8n. Use ao adicionar cobertura de testes para lógica de filtros, funções de pontuação, validadores, listas de palavras-chave, mapas de currículo ou qualquer lógica de código JavaScript puro em nós Code. Gera relatório agrupado de passou/falhou/pendente via Telegram. Execute ANTES e DEPOIS de qualquer alteração lógica para detectar regressões sem queimar créditos de API.

O que é n8n-evaluations-runner?

O skill **n8n Evaluations Runner** permite que desenvolvedores e engenheiros de IA criem e executem testes de unidade puramente lógicos para fluxos de trabalho n8n, sem consumir créditos de API. Ele é ideal para testar lógica de filtros, funções de pontuação, validadores, listas de palavras-chave, mapas de currículo ou qualquer função JavaScript pura em nós Code. O skill se baseia em um fluxo de trabalho n8n com acionamento manual, onde um nó Code executa todas as asserções, outro formata o relatório e um nó Telegram envia os resultados agrupados (passou/falhou/pendente) para um chat. A principal vantagem é fornecer uma rede de segurança contra regressões antes e depois de alterações lógicas, convertendo bugs passados em testes e priorizando a cobertura de caminhos de rejeição. Ele suporta qualquer plataforma que execute n8n e é uma ferramenta essencial para garantir a qualidade do código sem custos de API.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ashtonfeliciano/claude-skills-pack/tree/HEAD/skills/n8n-evaluations-runner

Installed? Explore more n8n skills: ashtonfeliciano/n8n-workflow-engineer, hubgunter4-ops/configurador-de-nodos-n8n, hubgunter4-ops/experto-en-n8n-mcp · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Executor de Avaliações n8n

Quando acionar

  • Ao adicionar ou modificar lógica de filtros, listas de palavras-chave, validadores ou mapas de currículo
  • Ao refatorar a lógica de função pura de um nó Code
  • Antes de mesclar uma alteração no fluxo de trabalho — guarda de regressão
  • Após um incidente de produção — codificar a falha em um teste
  • "Como faço testes unitários para código n8n?" / "Como testar sem gastar créditos de API?"

O que isso é (e não é)

Isso éIsso NÃO é
Um fluxo de trabalho n8n apenas lógico com entradas simuladasUm teste de integração contra APIs ativas
Sem chamadas externas, exceto o envio do relatório final — executa em ~3 segundosUm teste de desempenho
Contagens de passou/falhou/pendente enviadas para o TelegramUm substituto para testes manuais de fumaça de fluxo ponta a ponta
Uma rede de regressão para JS puro em nós CodeCobertura para comportamento de nós HTTP / Gmail / Telegram

Custo: sem créditos de API. Entradas simuladas, apenas em memória. O relatório do Telegram é a única chamada externa.

Arquitetura

[Acionador Manual] → [Executar Todos os Testes (nó Code)] → [Formatar Relatório (nó Code)] → [Enviar Relatório (Telegram)]

Um fluxo de trabalho por superfície lógica. Execute sob demanda.

Nó Code padrão do executor de testes

const results = [];

function assert(suite, testName, condition, detail) {
  results.push({ suite, test: testName, pass: condition, detail: detail || '' });
}

// ============================================================
// Suíte 1 — <nome>
// ============================================================

// Copie a função de produção VERBATIM aqui (não importe — nós Code não compartilham escopo)
function passaFiltroJs10(job) {
  // ... mesmo código do nó de produção ...
}

// Testes
assert('js-10', 'Trabalho com autorização rejeitado',
  !passaFiltroJs10({
    title: 'Redator Técnico',
    description: 'Autorização necessária.',
    location: 'remoto'
  }),
  'autorização necessária deve disparar rejeição');

assert('js-10', 'Redator técnico remoto válido passa',
  passaFiltroJs10({
    title: 'Redator Técnico',
    description: 'Escrever documentação de API para plataforma em nuvem.',
    location: 'remoto'
  }),
  'Redator técnico remoto válido deve passar em todos os filtros');

// Para funcionalidades ainda não implementadas:
results.push({
  suite: 'js-10',
  test: 'Limite de idade de 30 dias (PENDENTE — backlog)',
  pass: null,
  detail: 'Funcionalidade ainda não implementada. Adicione verificação de data postedAt e execute novamente.'
});

// ============================================================
// Resumo
// ============================================================

const passed  = results.filter(r => r.pass === true);
const failed  = results.filter(r => r.pass === false);
const pending = results.filter(r => r.pass === null);

return [{ json: {
  summary: { total: results.length, passed: passed.length, failed: failed.length, pending: pending.length },
  results, failed, pending
}}];

Formatador de relatório

const { summary, results } = $input.first().json;

const passIcon = '✅';
const failIcon = '❌';
const pendIcon = '⏳';
const topEmoji = summary.failed === 0 ? '🟢' : (summary.failed <= 3 ? '🟡' : '🔴');

const lines = [
  `<b>${topEmoji} <NOME> — Avaliação Lógica</b>`,
  `${passIcon} ${summary.passed} passaram  ${failIcon} ${summary.failed} falharam  ${pendIcon} ${summary.pending} pendentes`,
  ''
];

const suites = {};
for (const r of results) (suites[r.suite] = suites[r.suite] || []).push(r);

for (const [suite, tests] of Object.entries(suites)) {
  const suitePass = tests.every(t => t.pass !== false);
  lines.push(`<b>${suitePass ? passIcon : failIcon} ${suite}</b>`);
  for (const t of tests) {
    const icon = t.pass === true ? passIcon : (t.pass === false ? failIcon : pendIcon);
    lines.push(`  ${icon} ${t.test}`);
    if (t.pass !== true) lines.push(`    <i>→ ${(t.detail || '').substring(0, 140)}</i>`);
  }
  lines.push('');
}

const now = new Date().toLocaleString('pt-BR', {
  timeZone: 'UTC', dateStyle: 'short', timeStyle: 'short'
});
lines.push(`<i>Execução: ${now} UTC</i>`);

return [{ json: { message: lines.join('\n') } }];

Nó de envio do Telegram (padrão de variável de ambiente, sem credencial n8n)

{
  "method": "POST",
  "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/sendMessage",
  "sendBody": true,
  "specifyBody": "keypair",
  "bodyParameters": {
    "parameters": [
      { "name": "chat_id", "value": "={{ $env.TELEGRAM_CHAT_ID }}" },
      { "name": "text", "value": "={{ $json.message }}" },
      { "name": "parse_mode", "value": "HTML" }
    ]
  }
}

O que testar (ordem de prioridade)

  1. Cobertura de caminho de rejeição — toda razão pela qual um registro pode ser filtrado
  2. Condições de limite — no limite, logo abaixo, logo acima
  3. Fallbacks para entrada inválida — undefined, null, 0, 'Nenhum', tipo errado → padrão esperado
  4. Dados reais conhecidos como bons — pelo menos um exemplo de uma execução anterior confirmada como funcional
  5. Dados reais conhecidos como ruins — pelo menos um exemplo que causou um incidente anterior
  6. Correspondência de substring vs exata — por exemplo, 'Departamento de RH' vs 'Departamento de Recursos Humanos'
  7. Funcionalidades pendentes — escritas como pass: null para aparecerem nos relatórios como backlog

Convenção de nomenclatura de testes

<suíte>: <asserção legível por humano> com o campo de detalhe nomeando a regra subjacente ou referência de bug passado:

assert('js-22', 'Departamento de Recursos Humanos rejeitado',
  !isValidContact('Departamento de Recursos Humanos'),
  'A correspondência de substring BAD_CONTAINS_CONTACT deve capturar isso (correção do bug da Sessão 5)');

A regra de "converter bugs passados em testes"

Cada entrada em sua Biblioteca de Lições Aprendidas que nomeia uma entrada específica → comportamento errado é um teste esperando para ser escrito.

Exemplo de uma lição real:

"O Agregador de Cotações de Setor estava calculando a variação de 1 MÊS em vez de 1 DIA porque meta.previousClose retornava o preço de início do gráfico no intervalo=1mo."

→ Teste:

assert('aggregate', 'Variação de 1 dia calculada a partir de closes[], não de meta.previousClose',
  computeChange({
    chart: { result: [{ meta: { previousClose: 100 }, indicators: { quote: [{ close: [100, 98, 99, 105] }] } }] }
  }) === ((105 - 99) / 99) * 100,
  'meta.previousClose pode não ser confiável; deve usar closes[-2]');

Quando executar

  • Antes de qualquer alteração na lógica de filtros, listas de palavras-chave, validadores, mapas de currículo
  • Após a alteração → confirmar que não há regressões
  • Após a adição de qualquer entrada na Biblioteca de Lições → escrever o teste que a teria capturado
  • Pré-implantação de qualquer nova versão do fluxo de trabalho

Significado dos ícones de status

ÍconeSignificado
🟢 (verde)0 falhas — esta suíte passa; implante somente se suas outras verificações também passarem
🟡 (amarelo)1-3 falhas — implantação bloqueada até correção
🔴 (vermelho)4+ falhas — implantação bloqueada; provável quebra mais ampla

Pendentes (⏳) não contam para vermelho/amarelo — são rastreados separadamente como backlog. Testes pendentes são lacunas de cobertura: liste-os na nota de implantação.

Antipadrões

AntipadrãoO que fazer em vez disso
Testar contra APIs ativasApenas entradas simuladas — a suíte de avaliação é apenas lógica
Pular funcionalidades pendentes (perder visibilidade)Adicionar como pass: null com detalhe explicando o que está faltando
Importar código de produçãoCopiar verbatim — nós Code não compartilham escopo
Uma função de teste giganteUm assert() por asserção — relatório legível
Descartar o teste após corrigir o bugMantê-lo para sempre — essa é a guarda de regressão
Testar apenas o caminho felizCobertura de caminho de rejeição são os testes de maior valor
Executar apenas após uma alteraçãoExecutar ANTES E DEPOIS — confirma que você não introduziu regressões
Codificar ID do chat / token no JSON do fluxoUsar $env.TELEGRAM_BOT_TOKEN / $env.TELEGRAM_CHAT_ID

Lista de verificação pré-implantação

  • Fluxo de trabalho de avaliação executa em < 10 segundos
  • Todas as suítes agrupadas no relatório
  • Código de produção copiado verbatim (não parafraseado)
  • Pelo menos 1 teste por caminho de rejeição
  • Pelo menos 1 teste de "dados reais conhecidos como bons" por suíte
  • Funcionalidades pendentes representadas como pass: null com detalhe
  • Relatório cabe em uma mensagem do Telegram (< 4000 caracteres)

Referência

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Habilidades Relacionadas

ashtonfeliciano/n8n-workflow-engineer

Build, debug, and harden n8n workflows. Use when the user is editing n8n workflow JSON, debugging silent failures, working with Code nodes, Telegram / Gmail / HTTP Request nodes, scheduled triggers, paired-item tracking, dedup with static data, or doing bulk operations via the n8n REST API. Covers v2.x UI specifics. Not for non-n8n automation.

community

hubgunter4-ops/configurador-de-nodos-n8n

Ayuda a configurar nodos de n8n con reglas de dependencia complejas y conexiones de IA. Agiliza la creación de flujos de trabajo automatizados gestionando dependencias de nodos intrincadas e integraciones de IA.

community

hubgunter4-ops/experto-en-n8n-mcp

Guía a los desarrolladores a seleccionar y configurar herramientas y formatos de nodo del Protocolo de Contexto de Modelo MCP dentro de los flujos de trabajo de n8n. Proporciona orientación estructurada para integrar herramientas MCP.

community

caiqueDeOliveira-dev/homelab

HomeLab Agent — Gerencia Home Assistant, ESP32 satellites, dispositivos Zigbee/Matter/Thread, automações físicas, cameras, sensores. Camada de decisão e execução no hardware (não orquestração de software = Automação/n8n).

community

hubgunter4-ops/experto-en-n8n-mcp

Guía a los desarrolladores a seleccionar y configurar herramientas y formatos de nodo del Protocolo de Contexto de Modelo MCP dentro de los flujos de trabajo de n8n. Proporciona orientación estructurada para integrar herramientas MCP.

community

hubgunter4-ops/experto-en-validacion-de-n8n

Corrige errores de validación de n8n consultando un catálogo de errores integrado. Optimiza el proceso de depuración, permitiendo identificar rápidamente problemas y resolver problemas de configuración del flujo de trabajo.

community