Smithery Logo
MCPsSkillsDocsPricing
Login
Smithery Logo

Accelerating the Agent Economy

Resources

DocumentationPrivacy PolicySystem Status

Company

PricingAboutBlog

Connect

© 2026 Smithery. All rights reserved.

    proffesor-for-testing

    n8n-workflow-testing-fundamentals

    proffesor-for-testing/n8n-workflow-testing-fundamentals
    Productivity
    158
    2 installs

    About

    SKILL.md

    Install

    Install via Skills CLI

    or add to your agent
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    ├─
    ├─
    └─

    About

    Comprehensive n8n workflow testing including execution lifecycle, node connection patterns, data flow validation, and error handling strategies. Use when testing n8n workflow automation applications.

    SKILL.md

    n8n Workflow Testing Fundamentals

    When testing n8n workflows: 1. VALIDATE workflow structure before execution 2. TEST with realistic test data 3. VERIFY node-to-node data flow 4. CHECK error handling paths 5. MEASURE execution performance

    Quick n8n Testing Checklist:

    • All nodes properly connected (no orphans)
    • Trigger node correctly configured
    • Data mappings between nodes valid
    • Error workflows defined
    • Credentials properly referenced

    Critical Success Factors:

    • Test each execution path separately
    • Validate data transformations at each node
    • Check retry and error handling behavior
    • Verify integrations with external services

    Quick Reference Card

    When to Use

    • Testing new n8n workflows
    • Validating workflow changes
    • Debugging failed executions
    • Performance optimization
    • Pre-deployment validation

    n8n Workflow Components

    Component Purpose Testing Focus
    Trigger Starts workflow Reliable activation, payload handling
    Action Nodes Process data Configuration, data mapping
    Logic Nodes Control flow Conditional routing, branches
    Integration Nodes External APIs Auth, rate limits, errors
    Error Workflow Handle failures Recovery, notifications

    Workflow Execution States

    State Meaning Test Action
    running Currently executing Monitor progress
    success Completed successfully Validate outputs
    failed Execution failed Analyze error
    waiting Waiting for trigger Test trigger mechanism

    Workflow Structure Validation

    // Validate workflow structure before execution
    async function validateWorkflowStructure(workflowId: string) {
      const workflow = await getWorkflow(workflowId);
    
      // Check for trigger node
      const triggerNode = workflow.nodes.find(n =>
        n.type.includes('trigger') || n.type.includes('webhook')
      );
      if (!triggerNode) {
        throw new Error('Workflow must have a trigger node');
      }
    
      // Check for orphan nodes (no connections)
      const connectedNodes = new Set();
      for (const [source, targets] of Object.entries(workflow.connections)) {
        connectedNodes.add(source);
        for (const outputs of Object.values(targets)) {
          for (const connections of outputs) {
            for (const conn of connections) {
              connectedNodes.add(conn.node);
            }
          }
        }
      }
    
      const orphans = workflow.nodes.filter(n => !connectedNodes.has(n.name));
      if (orphans.length > 0) {
        console.warn('Orphan nodes detected:', orphans.map(n => n.name));
      }
    
      // Validate credentials
      for (const node of workflow.nodes) {
        if (node.credentials) {
          for (const [type, ref] of Object.entries(node.credentials)) {
            if (!await credentialExists(ref.id)) {
              throw new Error(`Missing credential: ${type} for node ${node.name}`);
            }
          }
        }
      }
    
      return { valid: true, orphans, triggerNode };
    }
    

    Execution Testing

    // Test workflow execution with various inputs
    async function testWorkflowExecution(workflowId: string, testCases: TestCase[]) {
      const results: TestResult[] = [];
    
      for (const testCase of testCases) {
        const startTime = Date.now();
    
        // Execute workflow
        const execution = await executeWorkflow(workflowId, testCase.input);
    
        // Wait for completion
        const result = await waitForCompletion(execution.id, testCase.timeout || 30000);
    
        // Validate output
        const outputValid = validateOutput(result.data, testCase.expected);
    
        results.push({
          testCase: testCase.name,
          success: result.status === 'success' && outputValid,
          duration: Date.now() - startTime,
          actualOutput: result.data,
          expectedOutput: testCase.expected
        });
      }
    
      return results;
    }
    
    // Example test cases
    const testCases = [
      {
        name: 'Valid customer data',
        input: { name: 'John Doe', email: 'john@example.com' },
        expected: { processed: true, customerId: /^cust_/ },
        timeout: 10000
      },
      {
        name: 'Missing email',
        input: { name: 'Jane Doe' },
        expected: { error: 'Email required' },
        timeout: 5000
      },
      {
        name: 'Invalid email format',
        input: { name: 'Bob', email: 'not-an-email' },
        expected: { error: 'Invalid email' },
        timeout: 5000
      }
    ];
    

    Data Flow Validation

    // Trace data through workflow nodes
    async function validateDataFlow(executionId: string) {
      const execution = await getExecution(executionId);
      const nodeResults = execution.data.resultData.runData;
    
      const dataFlow: DataFlowStep[] = [];
    
      for (const [nodeName, runs] of Object.entries(nodeResults)) {
        for (const run of runs) {
          dataFlow.push({
            node: nodeName,
            input: run.data?.main?.[0]?.[0]?.json || {},
            output: run.data?.main?.[0]?.[0]?.json || {},
            executionTime: run.executionTime,
            status: run.executionStatus
          });
        }
      }
    
      // Validate data transformations
      for (let i = 1; i < dataFlow.length; i++) {
        const prev = dataFlow[i - 1];
        const curr = dataFlow[i];
    
        // Check if expected data passed through
        validateDataMapping(prev.output, curr.input);
      }
    
      return dataFlow;
    }
    
    // Validate data mapping between nodes
    function validateDataMapping(sourceOutput: any, targetInput: any) {
      // Check all required fields are present
      const missingFields: string[] = [];
    
      for (const [key, value] of Object.entries(targetInput)) {
        if (value === undefined && sourceOutput[key] === undefined) {
          missingFields.push(key);
        }
      }
    
      if (missingFields.length > 0) {
        console.warn('Missing fields in data mapping:', missingFields);
      }
    
      return missingFields.length === 0;
    }
    

    Error Handling Testing

    // Test error handling paths
    async function testErrorHandling(workflowId: string) {
      const errorScenarios = [
        {
          name: 'API timeout',
          inject: { delay: 35000 }, // Trigger timeout
          expectedError: 'timeout'
        },
        {
          name: 'Invalid data',
          inject: { invalidField: true },
          expectedError: 'validation'
        },
        {
          name: 'Missing credentials',
          inject: { removeCredentials: true },
          expectedError: 'authentication'
        }
      ];
    
      const results: ErrorTestResult[] = [];
    
      for (const scenario of errorScenarios) {
        // Execute with error injection
        const execution = await executeWithErrorInjection(workflowId, scenario.inject);
    
        // Check error was caught
        const result = await waitForCompletion(execution.id);
    
        // Validate error handling
        results.push({
          scenario: scenario.name,
          errorCaught: result.status === 'failed',
          errorType: result.data?.resultData?.error?.type,
          expectedError: scenario.expectedError,
          errorWorkflowTriggered: await checkErrorWorkflowTriggered(execution.id),
          alertSent: await checkAlertSent(execution.id)
        });
      }
    
      return results;
    }
    
    // Verify error workflow was triggered
    async function checkErrorWorkflowTriggered(executionId: string): Promise<boolean> {
      const errorExecutions = await getExecutions({
        filter: {
          metadata: { errorTriggeredBy: executionId }
        }
      });
    
      return errorExecutions.length > 0;
    }
    

    Node Connection Patterns

    Linear Flow

    Trigger → Process → Transform → Output
    

    Testing: Execute once, validate each node output

    Branching Flow

    Trigger → IF → [Branch A] → Merge → Output
                  → [Branch B] →
    

    Testing: Test both branches separately, verify merge behavior

    Parallel Flow

    Trigger → Split → [Process A] → Merge → Output
                    → [Process B] →
    

    Testing: Validate parallel execution, check merge timing

    Loop Flow

    Trigger → SplitInBatches → Process → [Loop back until done] → Output
    

    Testing: Test with varying batch sizes, verify all items processed


    Common Testing Patterns

    Test Data Generation

    // Generate test data for common n8n patterns
    const testDataGenerators = {
      webhook: () => ({
        body: { event: 'test', timestamp: new Date().toISOString() },
        headers: { 'Content-Type': 'application/json' },
        query: { source: 'test' }
      }),
    
      slack: () => ({
        type: 'message',
        channel: 'C123456',
        user: 'U789012',
        text: 'Test message'
      }),
    
      github: () => ({
        action: 'opened',
        issue: {
          number: 1,
          title: 'Test Issue',
          body: 'Test body'
        },
        repository: {
          full_name: 'test/repo'
        }
      }),
    
      stripe: () => ({
        type: 'payment_intent.succeeded',
        data: {
          object: {
            id: 'pi_test123',
            amount: 1000,
            currency: 'usd'
          }
        }
      })
    };
    

    Execution Assertions

    // Common assertions for workflow execution
    const workflowAssertions = {
      // Assert workflow completed
      assertCompleted: (execution) => {
        expect(execution.finished).toBe(true);
        expect(execution.status).toBe('success');
      },
    
      // Assert specific node executed
      assertNodeExecuted: (execution, nodeName) => {
        const nodeData = execution.data.resultData.runData[nodeName];
        expect(nodeData).toBeDefined();
        expect(nodeData[0].executionStatus).toBe('success');
      },
    
      // Assert data transformation
      assertDataTransformed: (execution, nodeName, expectedData) => {
        const nodeOutput = execution.data.resultData.runData[nodeName][0].data.main[0][0].json;
        expect(nodeOutput).toMatchObject(expectedData);
      },
    
      // Assert execution time
      assertExecutionTime: (execution, maxMs) => {
        const duration = new Date(execution.stoppedAt) - new Date(execution.startedAt);
        expect(duration).toBeLessThan(maxMs);
      }
    };
    

    Agent Coordination Hints

    Memory Namespace

    aqe/n8n/
    ├── workflows/*          - Cached workflow definitions
    ├── test-results/*       - Test execution results
    ├── validations/*        - Validation reports
    ├── patterns/*           - Discovered testing patterns
    └── executions/*         - Execution tracking
    

    Fleet Coordination

    // Comprehensive n8n testing with fleet
    const n8nFleet = await FleetManager.coordinate({
      strategy: 'n8n-testing',
      agents: [
        'n8n-workflow-executor',  // Execute and validate
        'n8n-node-validator',     // Validate configurations
        'n8n-trigger-test',       // Test triggers
        'n8n-expression-validator', // Validate expressions
        'n8n-integration-test'    // Test integrations
      ],
      topology: 'parallel'
    });
    

    Related Skills

    • n8n-expression-testing - Expression validation
    • n8n-trigger-testing-strategies - Trigger testing
    • n8n-integration-testing-patterns - Integration testing
    • n8n-security-testing - Security validation

    Remember

    n8n workflows are JSON-based execution flows that connect 400+ services. Testing requires validating:

    • Workflow structure (nodes, connections)
    • Trigger reliability (webhooks, schedules)
    • Data flow (transformations between nodes)
    • Error handling (retry, fallback, notifications)
    • Performance (execution time, resource usage)

    With Agents: Use n8n-workflow-executor for execution testing, n8n-node-validator for configuration validation, and coordinate multiple agents for comprehensive workflow testing.

    Recommended Servers
    Vercel Grep
    Vercel Grep
    Repository
    proffesor-for-testing/agentic-qe
    Files