n8n-workflow-testing-fundamentals

n8n Workflow Testing Fundamentals

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "n8n-workflow-testing-fundamentals" with this command: npx skills add proffesor-for-testing/agentic-qe/proffesor-for-testing-agentic-qe-n8n-workflow-testing-fundamentals

n8n Workflow Testing Fundamentals

<default_to_action> When testing n8n workflows:

  • VALIDATE workflow structure before execution

  • TEST with realistic test data

  • VERIFY node-to-node data flow

  • CHECK error handling paths

  • 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 </default_to_action>

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' &#x26;&#x26; 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.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

api-testing-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

compatibility-testing

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

regression-testing

No summary provided by upstream source.

Repository SourceNeeds Review