Communityn8ngithub.com

ashtonfeliciano/n8n-evaluations-runner

Créez et exécutez des suites de tests logiques sans coût d'API pour les workflows n8n. Utilisez-le lors de l'ajout de couverture de test pour les filtres, les fonctions de scoring, les validateurs, les listes de mots-clés, les cartes de résumé ou toute logique de Code node en pur JavaScript. Produit un rapport groupé (réussite/échec/en attente) via Telegram. Exécutez AVANT et APRÈS tout changement logique pour détecter les régressions sans dépenser de crédits API.

Qu'est-ce que n8n-evaluations-runner ?

Ce skill permet d'ajouter une couverture de tests unitaires pour les parties logiques pures de vos workflows n8n, sans consommer de crédits API. Au lieu de lancer des tests d'intégration coûteux, vous créez un workflow dédié qui exécute des assertions JavaScript simples sur des entrées simulées. Le résultat est un rapport formaté et envoyé via Telegram, indiquant le nombre de tests réussis, échoués et en attente. Il est idéal pour les développeurs qui souhaitent sécuriser leurs filtres, validateurs et fonctions de scoring, et pour transformer les bugs passés en tests de non-régression. Le skill est compatible avec n8n et propose une architecture simple : un déclencheur manuel, un nœud Code pour les tests, un formateur de rapport et un nœud Telegram pour l'envoi. L'approche privilégie la copie littérale du code de production dans le nœud de test, car les Code nodes ne partagent pas la portée. Il inclut des conventions de nommage, une priorisation des tests (chemins de rejet, conditions limites, données réelles connues) et des anti-patrons à éviter.

Compatible avec~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 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Exécuteur d'évaluations n8n

Quand déclencher

  • Ajout ou modification d'une logique de filtre, de listes de mots-clés, de validateurs ou de cartes de résumé
  • Refactorisation de la logique d'une fonction pure dans un Code node
  • Avant de fusionner une modification de workflow — garde de régression
  • Après un incident de production — transformer l'échec en test
  • « Comment effectuer des tests unitaires du code n8n ? » / « Comment tester sans utiliser de crédits API ? »

Ce que c'est (et ce que ce n'est pas)

Ceci estCeci n'est PAS
Un workflow n8n uniquement logique avec des entrées simuléesUn test d'intégration contre des API en production
Aucun appel externe sauf l'envoi final du rapport — s'exécute en ~3 secondesUn test de performance
Des compteurs réussite/échec/en attente envoyés à TelegramUn remplacement des tests de fumée manuels du flux de bout en bout
Un filet de régression pour le JS pur dans les Code nodesUne couverture pour le comportement des nœuds HTTP / Gmail / Telegram

Coût : aucun crédit API. Entrées simulées, uniquement en mémoire. L'envoi du rapport Telegram est le seul appel externe.

Architecture

[Déclencheur manuel] → [Exécuter tous les tests (Code node)] → [Formater le rapport (Code node)] → [Envoyer le rapport (Telegram)]

Un workflow par surface logique. Réexécution à la demande.

Nœud Code standard du moteur de test

const results = [];

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

// ============================================================
// Suite 1 — <nom>
// ============================================================

// Copiez la fonction de production LITTÉRALEMENT ici (n'importez pas — les Code nodes ne partagent pas la portée)
function passesJs10Filter(job) {
  // ... même code que le nœud de production ...
}

// Tests
assert('js-10', 'Offre d'emploi avec habilitation rejetée',
  !passesJs10Filter({
    title: 'Rédacteur technique',
    description: 'Habilitation requise.',
    location: 'télétravail'
  }),
  'l'habilitation requise doit déclencher le rejet');

assert('js-10', 'Rédacteur technique valide en télétravail passe',
  passesJs10Filter({
    title: 'Rédacteur technique',
    description: 'Rédiger la documentation API pour une plateforme cloud.',
    location: 'télétravail'
  }),
  'Un rédacteur technique valide en télétravail doit passer tous les filtres');

// Pour les fonctionnalités non encore implémentées :
results.push({
  suite: 'js-10',
  test: 'Limite d'âge de 30 jours (EN ATTENTE — backlog)',
  pass: null,
  detail: 'Fonctionnalité pas encore implémentée. Ajouter la vérification de la date postedAt, puis réexécuter.'
});

// ============================================================
// Résumé
// ============================================================

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
}}];

Formateur de rapport

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

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

const lines = [
  `<b>${topEmoji} <NOM> — Évaluation logique</b>`,
  `${passIcon} ${summary.passed} réussis  ${failIcon} ${summary.failed} échoués  ${pendIcon} ${summary.pending} en attente`,
  ''
];

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('fr-FR', {
  timeZone: 'UTC', dateStyle: 'short', timeStyle: 'short'
});
lines.push(`<i>Exécuté : ${now} UTC</i>`);

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

Nœud d'envoi Telegram (modèle avec variables d'environnement, sans identifiant 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" }
    ]
  }
}

Ce qu'il faut tester (par ordre de priorité)

  1. Couverture des chemins de rejet — chaque raison pour laquelle un enregistrement peut être filtré
  2. Conditions limites — au seuil, juste en dessous, juste au-dessus
  3. Gestion des entrées invalides — undefined, null, 0, 'None', mauvais type → valeur par défaut attendue
  4. Données réelles connues comme valides — au moins un exemple d'une exécution passée confirmée
  5. Données réelles connues comme invalides — au moins un exemple ayant causé un incident passé
  6. Correspondance de sous-chaîne vs exacte — par exemple, 'Service RH' vs 'Département des Ressources Humaines'
  7. Fonctionnalités en attente — écrites avec pass: null pour apparaître dans les rapports comme backlog

Convention de nommage des tests

<suite> : <assertion lisible> avec le champ detail nommant la rgle sous-jacente ou la référence de l'ancien bug :

assert('js-22', 'Département des Ressources Humaines rejeté',
  !isValidContact('Département des Ressources Humaines'),
  'La correspondance de sous-chaîne BAD_CONTAINS_CONTACT doit intercepter cela (correction du bug de la Session 5)');

La règle « convertir les bugs passés en tests »

Chaque entrée de votre Bibliothèque de leçons apprises qui nomme une entrée spécifique → un comportement erroné est un test qui attend d'être écrit.

Exemple tiré d'une leçon réelle :

« Aggregate Sector Quotes calculait la variation sur 1 MOIS au lieu de 1 JOUR car meta.previousClose renvoyait le prix de début du graphique pour un intervalle de 1 mois. »

→ Test :

assert('aggregate', 'variation sur 1 jour calculée à partir de closes[], pas de meta.previousClose',
  computeChange({
    chart: { result: [{ meta: { previousClose: 100 }, indicators: { quote: [{ close: [100, 98, 99, 105] }] } }] }
  }) === ((105 - 99) / 99) * 100,
  'meta.previousClose peut être peu fiable ; doit utiliser closes[-2]');

Quand exécuter

  • Avant toute modification de la logique de filtre, des listes de mots-clés, des validateurs, des cartes de résumé
  • Après la modification → confirmer l'absence de régressions
  • Après l'ajout d'une entrée dans la Bibliothèque de leçons → écrire le test qui l'aurait interceptée
  • Pré-déploiement de toute nouvelle version du workflow

Signification des icônes de statut

IcôneSignification
🟢 (vert)0 échecs — cette suite passe ; déployez uniquement si vos autres vérifications passent aussi
🟡 (jaune)1 à 3 échecs — déploiement bloqué jusqu'à correction
🔴 (rouge)4 échecs ou plus — déploiement bloqué ; probablement une rupture plus large

Les tests en attente (⏳) ne sont pas comptés dans le rouge/jaune — ils sont suivis séparément comme backlog. Les tests en attente sont des lacunes de couverture : listez-les dans la note de déploiement.

Anti-patrons

Anti-patronQue faire à la place
Tester contre des API en productionEntrées simulées uniquement — la suite d'évaluation est purement logique
Ignorer les fonctionnalités en attente (perte de visibilité)Ajouter avec pass: null et un détail expliquant ce qui manque
Importer le code de productionCopier littéralement — les Code nodes ne partagent pas la portée
Une fonction de test géanteUne assert() par assertion — rapport lisible
Supprimer le test après la correction d'un bugLe conserver pour toujours — c'est la garde de régression
Tester uniquement le scénario idéalLa couverture des chemins de rejet est le test à plus forte valeur ajoutée
Exécuter uniquement après une modificationExécuter AVANT ET APRÈS — confirme que vous n'avez pas introduit de régressions
Coder en dur l'ID de chat / le jeton dans le JSON du workflowUtiliser $env.TELEGRAM_BOT_TOKEN / $env.TELEGRAM_CHAT_ID

Liste de vérification pré-déploiement

  • Le workflow d'évaluation s'exécute en moins de 10 secondes
  • Toutes les suites sont regroupées dans le rapport
  • Le code de production est copié littéralement (pas paraphrasé)
  • Au moins 1 test par chemin de rejet
  • Au moins 1 test « données réelles connues valides » par suite
  • Les fonctionnalités en attente sont représentées avec pass: null et un détail
  • Le rapport tient dans un seul message Telegram (< 4000 caractères)

Références

Individual skills in this repo

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

Skills associés

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